title: How to disable animation root motion

text:
# Question
Title: How to disable animation root motion
I downloaded some animations with root motion from Mixamo and the corresponding character model.

After created an animator with those animations and added it to the character game object, the root motion was causing the transform to move around, which was not supposed to happen.

I tried to uncheck "Apply Root Motion", and set "Motion - Root Motion Node" to "None", but neither of them worked.

The only thing that worked is checking "Loop Time - Loop Pose", but it doesn't make much sense to mess with root motion, someone even proposed it shouldn't disable root motion.

So, how to disable animation root motion?

Also I'm confused, is root motion optional? Must I get animations without root motion if it's not needed?

# Answer
This page explains how Unity root motion animation works: https://docs.unity3d.com/Manual/RootMotion.html

**To understand the problem, read ahead or skip to "how to fix" in end the for solutions:**

Body root transform/node can be thought as "reference point" of skeleton relative to 3d space where it and it's animation exists. In Unity humanoid rigs, it is the only world space node for skeleton according to Unity manual (see link above).

In animation software animations are usually done either "in-place" or by moving characters in scene space. It might be easier to animate a run loop "threadmill" style, so that legs and arms swing yet hips stay on place (character does not translate in 3d scene space). On the other hand, it might be easier to animate a jump and roll over fence so that character moves in 3d scene space, this way feet and hands can be firmly planted on key moments.

According to Unity manual, Unity's implementation of root motion concept works like this: Root motion is calculated from body transform node in run-time. In animation clip, body transform might move relative to animation scene "world space", but what Unity does, it computes this offset every frame, and then applies it to game object as movement instead, and what they don't say - removes it from root node. By toggling "Root Transform Position (XZ), Bake into pose on, you'll see that this process is reversed, and you'll see your character sprint away from animation clip origin, if your animation clip skeleton is animated moving in scene space, that is. When you toggle bake into pose off, you see that world grid starts to travel under character, meaning that Unity has removed the root x and y movement (transform/GameObject is moving).

(Reasons for this are understandable but Unity explanation for this is not very clear. For example, Unreal engine explains it's own implementation quite clearly: https://docs.unrealengine.com/en-US/Engine/Animation/RootMotion)

Mixamo animations might be animated / captured this way moving in 3d space, and will have skeleton root moving away from origin. But if this root node movement exists, it results in unity root motion values, which in turn will be moving GameObject in scene. If there is movement in animation clip character's hips (whatever the topmost joint is), Unity will see it as offset, and will move your character Transform/GameObject in scene. There are no check boxes to remove x and z animation from character root node IIRC.

**How to fix:**

a. Recreate animation export in Mixamo if possible, so that character is animated in-place (mentioned already in comments).

b. Remove root offset movement in Unity. Make a copy of animation clip (so that you can change it), open it in Animation Window then find the skeleton root node, select and delete keyframes for translation animation from both x- and z-axis, and leave y-axis movement untouched.

c. Take animation back into animation software (Maya) or motion editing/authoring software (Motion Builder) and modify the animation clip to remove the root animation.
> 5 votes

# Answer
In the inspector for the animation file (e.g walking.fbx), in the Animation pane, if you check both "Loop time" and "Loop Pose" then the animation will be in place.

Another technique is in the animation window, the base animation will be read-only, but if you copy all the properties into a new animation and remove the Hip motion you should be in place.

Also, and maybe this is more adapted to your particular issue. If you set the rig type to humanoid, then you will be able to "Bake into pose" XZ, Y and rotation. Which will deactivate root motion for the particular parameter.
> 6 votes

# Answer
Other than turning off root motion in the animator, I also loop the animation and the pose too. Here is a video on how to do that.
> 1 votes

# Answer
Assuming there is a humanoid animation: copy all the keyframes (Ctrl+a,Ctrl+c), create a new animation clip (Create \> Animation), paste the keyframes, find "Animator.RootT" and expand it. Assuming the model moves in forward Z, right click on "RootT.Z" and click "Remove property."
> 0 votes

# Answer
When importing a Maximo I found that not including an animation alleviates the Unity hanging crouch default position in game play or animation preview. The avatar selection in the inspector animator must be cleared also.
> 0 votes

# Answer
This is an old question, but it's still relevant and one of the top result when searching for a solution and, yet, the main solution is not yet in any so here you go...

The "Root Transform" check boxes in any animation are used to apply the movement of the root object to the the in-game character transform. If it's checked ON, it allows the root object translation (movements) to be copied onto the object's transform in an additive while if it's OFF, the animation motion will be added to the object's transform, but will also include the part where it loop back (for example, with a walk animation with Root Motion, it will looks like the character is rubber-banding back to its start position once the animation is done.)

"Root Transform" is useful in cases, for example, where you want to customize the movement of the character based on its animation without coding all the variances in speed and direction. (For example, if you want the character to step forward during an attack or if you want a character to move at the representative speed of its steps and not just moon-walking.)

Outside of Unity, there are a lot of ways of handling the issue (some are easy and some are time-consuming), but Unity itself has a built-in way that is relatively straight forward.

To do it directly in Unity (for example, with animation you got from some assets purchased from the Asset Store), go to the FBX file, in the Unity Project menu, that contains the animation(s) you need. (Note: The animations HAS to be applied to the "Animation" tab of the FBX first.) Open the FBX file content by clicking on the arrow right or left to it (depending on the type of display). You should see each animation set in the FBX (the icon is a cyan triangle with some white or black lines on its left) Select all the animation, copy (CTRL+C) and paste (CTRL+V) them outside of the FBX file. Unity will generate animation files based on the animation settings set in the FBX.

Those animation files that get copied and pasted can be edited in the "Animation" menu in Unity. You can remove the root motion from those file by looking up, in the "Animation" menu for the Animator.Root.T line of keyframe. Each animated bones in the animation will have 2 lines of keys. One is ending with "T" which is the Transform (movement) and one is the "Q" which is the Quaternion (rotation). You might think of just deleting them both, but remember that it will remove ALL position and rotation references. If you got a skill that turn the character 360 degrees for an attack, that turn will most likely disappears if you remove the "Root Q" keys. At the same time, if you just remove the "Root T" keys, the character might end up being offset from the proper position.

So, the trick is to uncheck the Root Transform Rotation and Position(Y) and (XZ), which can be done in the animation file you copied and pasted, go to the "Root Q" and "Root T" line of animation keys in the Animation menu. If you don't need any rotation (like for a walking/run that is straight forward), you can deleted the "Root Q" line of keys. (you can delete a whole line just by clicking on the white dot right of the "Root Q" and select "Remove Property".) For the "Root T", line, it needs a bit more subtleties: You got to open the drop-down (arrow right of the animation key line name) which will reveal the 3D movements axes (X,Y,Z) of the animation root. You can delete the property (as previously mentioned) for the X and Z unless you need them (for specific animations) and if you don't need any of the Y keys, you can just delete all keys of that line (do NOT delete the property), except for the first key. This can easily be done by selecting the 2nd key, then while holding shift, click on the last key and then press Delete. If There's only 1 key (the first one), the animation will not have root motion, but it will still have its proper "default" position.

If you delete the whole line of keys on "Root T.y", there's a chance your character will be positioned with its pelvis position as its "origin" instead of its root position, resulting with your character being quite lower than anticipated visually.
> 0 votes

---
Tags: unity, animation
---


title: Fisheye effect on 3D projection

text:
# Question
Title: Fisheye effect on 3D projection
I'm rendering a maze with raycasting in Scratch.

When I'm far away, the walls look nice, but when I'm near the walls they get a weird fisheye effect:

Here is the code for the raycasting:

And the code for drawing:

As mentioned in the comments, there are other posts here about solving this problem in other frameworks; I'm having difficulty translating those answers into the Scratch.

# Answer
Although as noted above we have lots of past Q&A about solving this problem in other frameworks, I think it's understandable if a Scratch user would have difficulty translating that code into the equivalent LEGO-block representation.

Here's the corrected raycasting routine:

The changes I made:

1. I've added a "linear offset" variable, representing the position of the column of the screen this ray represents: -48 for the left-most column, +48 for the right-most, and 0 in the middle.
2. The "repeat 96" loop now increments linear offset, not angular offset. As I explain in this answer and this one, incrementing by angle only makes sense if you're rendering on a curved screen that wraps around your head, so the columns of pixels have equal angular spacing.

When we're rendering on a flat monitor, columns of pixels have equal linear spacing, which means the angular spacing is non-uniform: columns of pixels are further apart in the angular space of our eye where the surface of the monitor is perpendicular to our gaze, and they bunch up as the monitor recedes away to either side, through foreshortening. So...
3. We calculate the "angular offset" from the linear offset, using the trigonometric arctangent function to get this non-uniformity. You can think of the divisor there as being the distance from the monitor to your eye: smaller divisors = sitting closer to the window = seeing more at the edges (wider field of view), though this can also make the image look distorted if the player is actually viewing from farther away.
4. The depth value we use to draw the walls should measure only the forward component of the depth. Things don't get shorter in linear perspective when they move left and right parallel to the image plane, even through the distance the ray has to travel diagonally to reach them increases. So we multiply by cosine (adjacent divided by hypotenuse) to extract just the forward component of the ray's length.

Now we get nice straight-line walls:

You can see the walls stay straight (to within the limited resolution of the discrete ray hops) even up-close.
> 0 votes

---
Tags: 3d, raycasting, scratch
---


# Question
Title: How to convert from object space to clip space
I want to animate foliage with vertex animation but I have wrong output because I can't correctrly transform from object space to clip space, and my foliage goes off the model. How Can I convert in corrent way the space?

```
fragmentInput vertexProgram(vertexInput data)
{
    UNITY_SETUP_INSTANCE_ID(data);

    fragmentInput output;
    float3 positionWS = TransformObjectToWorld(data.positionOS);
    output.positionCS = TransformWorldToHClip(positionWS);
    output.positionWSAndFog = float4(positionWS, ComputeFogFactor(output.positionCS.z));

    VertexNormalInputs normalInput = GetVertexNormalInputs(data.normalOS, data.tangentOS);
    output.normalWS = normalInput.normalWS;
    output.tangentWS = normalInput.tangentWS;
    output.bitangentWS = normalInput.bitangentWS;

    output.uv = TRANSFORM_TEX(data.uv, _BaseColor);

    output.viewDirectionWS = GetWorldSpaceViewDir(positionWS);

#ifdef _MAIN_LIGHT_SHADOWS
    output.shadowCoord = TransformWorldToShadowCoord(positionWS);
#endif

    OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV);
    OUTPUT_SH(output.normalWS, output.vertexSH);

    // I'm starting my animation from here
    float4 worldPos = mul(data.positionOS, unity_ObjectToWorld);
    float2 samplePos = worldPos.xz / _WorldSize.xz;
    samplePos += _Time.x * _WindSpeed.xy;
    float windSample = tex2Dlod(_WindTex, float4(samplePos, 0, 0));

    output.positionCS.x += sin(_WaveSpeed * windSample) * _WaveAmp;
    output.positionCS.z += cos(_WaveSpeed * windSample) * _WaveAmp;

    // then I sholud somehow convert to clip space if im not wrong
    return output;
}

```

Here what I've got:

# Answer
\_WaveAmp value was too high and affect possition of vertecies. Around 0.08 is ok

```
    output.positionCS.x += sin(_WaveSpeed * windSample) * _WaveAmp;
    output.positionCS.z += cos(_WaveSpeed * windSample) * _WaveAmp;

```
> 0 votes

# Answer
It looks to me like what you want is something like this. Start with the beginning of the shader until it computes the position in world space:

```
fragmentInput vertexProgram(vertexInput data)
{
    UNITY_SETUP_INSTANCE_ID(data);

    fragmentInput output;
    float3 positionWS = TransformObjectToWorld(data.positionOS);

```

Now add your code that modifies the world space position. You don't need your line `float4 worldPos = ...` since `positionWS` already contains the world space position:

```
    float2 samplePos = positionWS.xz / _WorldSize.xz;
    samplePos += _Time.x * _WindSpeed.xy;
    float windSample = tex2Dlod(_WindTex, float4(samplePos, 0, 0));

    positionWS.x += sin(_WaveSpeed * windSample) * _WaveAmp;
    positionWS.z += cos(_WaveSpeed * windSample) * _WaveAmp;

```

Now you can continue with the rest of the shader, that computes the clip space position from the world space position:

```
    output.positionCS = TransformWorldToHClip(positionWS);
    output.positionWSAndFog = float4(positionWS, ComputeFogFactor(output.positionCS.z));

    VertexNormalInputs normalInput = GetVertexNormalInputs(data.normalOS, data.tangentOS);
    output.normalWS = normalInput.normalWS;
    output.tangentWS = normalInput.tangentWS;
    output.bitangentWS = normalInput.bitangentWS;

    output.uv = TRANSFORM_TEX(data.uv, _BaseColor);

    output.viewDirectionWS = GetWorldSpaceViewDir(positionWS);

#ifdef _MAIN_LIGHT_SHADOWS
    output.shadowCoord = TransformWorldToShadowCoord(positionWS);
#endif

    OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV);
    OUTPUT_SH(output.normalWS, output.vertexSH);

    return output;
}

```

Doing it this way, your wind displacement also affects the shadow.
> 0 votes

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


# Question
Title: How to subdivide an octahedron into a sphere?
For a game I'm making, I have to tessellate an octahedron into a sphere on the GPU (shaders). What I've done is I've successfully tessellated the faces, but I'm having trouble subdividing more spaces, or in better terms, create more faces on the shape. I'm using tessellation shaders to help with this. I would use geometry shaders, but from what I learned, I shouldn't because it makes the program performance worse, and it isn't worth using because tessellation shaders can already created new geometry like geometry shaders. TES (Tessellation Evaluation Shader)

```
#version 450 core

// from control shader
layout(triangles, equal_spacing, ccw) in;

// input from control shader
in vec3 vertex_coord[];
// output vec
out vec3 vert;

// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    // patch coords
    float u = gl_TessCoord.x;
    float v = gl_TessCoord.y;
    float w = gl_TessCoord.z;

    // retrieve control point vertex coordinates
    vec3 t00 = vertex_coord[0];
    vec3 t01 = vertex_coord[1];
    vec3 t10 = vertex_coord[2];

    // bi-linearly interpolate vertex coordinate across patch
    vec3 t0 = (t01 - t00) * w + t00;
    vec3 t1 = (t00 - t10) * v + t01;
    vec3 t2 = (t10 - t01) * u + t10;
    vec3 vert = (t1 - t0 - t2) * v + t0;

    // retrieve control point position coordinates
    vec4 p00 = gl_in[0].gl_Position;
    vec4 p01 = gl_in[1].gl_Position;
    vec4 p10 = gl_in[2].gl_Position;

    // compute patch surface normal
    vec4 u_vec = p01 - p00;
    vec4 v_vec = p10 - p00;
    vec4 w_vec = p10 - p01;
    vec4 normal = normalize( vec4(cross(u_vec.xyz, v_vec.xyz), 0) );

    // bi-linearly interpolate position coordinate across patch
    vec4 p0 = (p01 - p00) * u + p00;
    vec4 p1 = (p00 - p10) * v + p10;
    vec4 p2 = (p01 - p00) * w + p01;
    vec4 p = (p1 - p0)  * w + p0;

    // displace point along normal
    //p += normal;

    // output patch point position in clip space
    gl_Position = projection * view * model * p;
}

```

For a reference, this is the type of subdivision I'm trying to go for, except it's not conducted on the CPU, it's on the GPU, for better performance, and because it seems to be easier to do than on the CPU.

After modifying the tessellation variables above, I came a little bit closer to what I was going for but still not quite (captured in wireframe mode)

As per @user253751's suggestion, I normalized the vertex coordinates and it didn't work as well as before. A birds eye view of the result:  Here are the original vertices that created the octahedron in case that might help someone better understand the problem.

```
float vertices[] = {
    //top-north-east
     0.0,  1.0,  0.0,
     0.0,  0.0,  1.0,
     1.0,  0.0,  0.0,

    //top-north-west
     0.0,  1.0,  0.0,
    -1.0,  0.0,  0.0,
     0.0,  0.0,  1.0,

    //top-south-west
     0.0,  1.0,  0.0,
     0.0,  0.0, -1.0,
    -1.0,  0.0,  0.0,

    //top-south-east
     0.0,  1.0,  0.0,
     1.0,  0.0,  0.0,
     0.0,  0.0, -1.0,

    //bottom-north-east
     0.0, -1.0,  0.0,
     1.0,  0.0,  0.0,
     0.0,  0.0,  1.0,

    //bottom-north-west
     0.0, -1.0,  0.0,
     0.0,  0.0,  1.0,
    -1.0,  0.0,  0.0,

    //bottom-south-west
     0.0, -1.0,  0.0,
    -1.0,  0.0,  0.0,
     0.0,  0.0, -1.0,

    //bottom-south-east
     0.0, -1.0,  0.0,
     0.0,  0.0, -1.0,
     1.0,  0.0,  0.0,
};

```

I also found these Wikipedia articles and a youtube video to help visualize my desired outcome for the program.

https://en.wikipedia.org/wiki/Geodesic\_polyhedron

https://en.wikipedia.org/wiki/N-sphere#Octahedral\_sphere

https://www.youtube.com/watch?v=CUBitJ7g9gc

# Answer
> 2 votes
After over a week of work, I have finally (partially) solved the problem. I was doing too much in the TE shader, so, using a tutorial I have linked right here https://prideout.net/blog/old/blog/index.html@p=48.html I normalized variables in certain ways (I think it's spherical coordinates but I'm not sure) and that resulted in me solving the problem

Here's the new TES that works

```
#version 450 core

// from control shader
layout(triangles, equal_spacing, cw) in;

// input from control shader
in vec3 vertex_coord[];
// output vec
out vec3 vert;

// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    // make it into a sphere
    vec3 u = gl_TessCoord.x * vertex_coord[0];
    vec3 v = gl_TessCoord.y * vertex_coord[1];
    vec3 w = gl_TessCoord.z * vertex_coord[2];
    vec3 pos = normalize(u + v + w);

    // output patch point position in clip space
    gl_Position = projection * view * model * vec4(pos, 1.0);
}

```

To any future viewers who are trying this as well, here are the main parts of the program

TCS

```
#version 450 core

// specify control points per output per patch
// control size of input and output arrays
layout(vertices=3) out;
// input from vertex shader
in vec3 vert_coord[];
// output to evaluation shader
out vec3 vertex_coord[];

// for tessellation
uniform mat4 view;
uniform mat4 model;

void main()
{
    // pass attributes through
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
    vertex_coord[gl_InvocationID] = vert_coord[gl_InvocationID];

    // control tessellation
    if(gl_InvocationID==0)
    {
        /* dynamic tessellation */
        // first: define rendering constants to control tessellation
        const float MIN_TESS_LEVEL = 4;
        const float MAX_TESS_LEVEL = 64;
        const float MIN_DISTANCE = 20;
        const float MAX_DISTANCE = 800;
        // second: transform each vertex into each eye
        vec4 eye_space_pos_1 = view * model * gl_in[0].gl_Position;
        vec4 eye_space_pos_2 = view * model * gl_in[1].gl_Position;
        vec4 eye_space_pos_3 = view * model * gl_in[2].gl_Position;
        // third: distance from camera scaled between 0 and 1
        float distance_1 = clamp((abs(eye_space_pos_1.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_2 = clamp((abs(eye_space_pos_2.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_3 = clamp((abs(eye_space_pos_3.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        // fourth: interpolate edge tessellation level based on closer vertex
        float tess_level_1 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_3, distance_1));
        float tess_level_2 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_1, distance_2));
        float tess_level_3 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_2, distance_1));
        // fifth: set the corresponding outer tessellation levels
        gl_TessLevelOuter[0] = tess_level_1;
        gl_TessLevelOuter[1] = tess_level_2;
        gl_TessLevelOuter[2] = tess_level_3;
        // sixth: set the inner tessellation levels
        gl_TessLevelInner[0] = max(tess_level_2, tess_level_1);
        gl_TessLevelInner[1] = max(tess_level_1, tess_level_3);
    }
}

```

Octahedron verticies and indices

```
     unsigned int draw_calls = 3;
     float vertices[] = {
     //top-north-east
     0.0,  1.0,  0.0,
     0.0,  0.0,  1.0,
     1.0,  0.0,  0.0,

    //top-north-west
     0.0,  1.0,  0.0,
    -1.0,  0.0,  0.0,
     0.0,  0.0,  1.0,

    //top-south-west
     0.0,  1.0,  0.0,
     0.0,  0.0, -1.0,
    -1.0,  0.0,  0.0,

    //top-south-east
     0.0,  1.0,  0.0,
     1.0,  0.0,  0.0,
     0.0,  0.0, -1.0,

    //bottom-north-east
     0.0, -1.0,  0.0,
     1.0,  0.0,  0.0,
     0.0,  0.0,  1.0,

    //bottom-north-west
     0.0, -1.0,  0.0,
     0.0,  0.0,  1.0,
    -1.0,  0.0,  0.0,

    //bottom-south-west
     0.0, -1.0,  0.0,
    -1.0,  0.0,  0.0,
     0.0,  0.0, -1.0,

    //bottom-south-east
     0.0, -1.0,  0.0,
     0.0,  0.0, -1.0,
     1.0,  0.0,  0.0,
};

unsigned int indices[] = {
    // first triangle
    0, 1, 2,
    // second triangle
    3, 4, 5,
    // third triangle
    6, 7, 8,
    // fourth triangle
    9, 10, 11,
    // fifth triangle
    12, 13, 14,
    // sixth triangle
    15, 16, 17,
    // seventh triangle
    18, 19, 20,
    // eighth triangle
    21, 22, 23
};

```

Tessellation specifications and draw call

```
#define NUM_PATCH_PTS 3
unsigned int draw_calls = 3;
// max tessellation points / patches
glPatchParameteri(GL_PATCH_VERTICES, NUM_PATCH_PTS);
glBindVertexArray(vao);
glDrawArrays(GL_PATCHES, 0, draw_calls*draw_calls*NUM_PATCH_PTS);

```

This is what it looks like now

As you can see, around 80% of the sphere is rendered, so it's not perfect, but I'm working on it and when I fix this, I will update this answer, this might take a while...

EDIT: Ok, so 2 months later but I finally fixed the sphere problem. After I went to another forum over the weekend and posted my problem, I got help. It turns out that the coordinates were wrong. The problematic ones were top-north-east and bottom-south-east. Here are the new and improved coordinates as well as proof that it really works.

```
    float vertices[] = {
    //top-north-east
     0.0f, 1.0f,  0.0f,
     0.0f,  0.0f,  1.0f,
     1.0f,  0.0f,  0.0f,

    //top-north-west
     0.0f,  1.0f,  0.0f,
    -1.0f,  0.0f,  0.0f,
     0.0f,  0.0f,  1.0f,

    //top-south-west
     0.0f,  1.0f,  0.0f,
     0.0f,  0.0f, -1.0f,
    -1.0f,  0.0f,  0.0f,

    //top-south-east
     0.0f, -1.0f,  0.0f,
     1.0f,  0.0f,  0.0f,
     0.0f,  0.0f, -1.0f,

    //bottom-north-east
     0.0f, -1.0f,  0.0f,
     1.0f,  0.0f,  0.0f,
     0.0f,  0.0f,  1.0f,

    //bottom-north-west
     0.0f, -1.0f,  0.0f,
     0.0f,  0.0f,  1.0f,
    -1.0f,  0.0f,  0.0f,

    //bottom-south-west
     0.0f, -1.0f,  0.0f,
    -1.0f,  0.0f,  0.0f,
     0.0f,  0.0f, -1.0f,

    //bottom-south-east
     0.0f, 1.0f,  0.0f,
     0.0f,  0.0f, -1.0f,
     1.0f,  0.0f,  0.0f
};

```

Took two months but I told everyone I would be back to solve the problem!

---
Tags: opengl, shaders, glsl, sphere, tessellation
---


# Question
Title: How do I know currently active TMP_InputField in unity
I have a list of TMP\_InputFields on my canvas like OTP boxes. I made it in such a way that the cursor automatically moves to the next box once the user types something in the current box. I am working on the backspace such that when it's pressed, the current box gets emptied and the previous box gets activated for the user.

I am having issues with getting the currently active TMP\_InputFields out of these input fields. By active, I mean the box that currently has the cursor. I have tried looping through the list and checking ".enabled = true" and "isFocused" but both are not doing what I want.

Can anyone guide me through, please

# Answer
> 0 votes
The `.isFocused` is working as it should. Here is a minimal example that prints the current selected InputField.

```
public TMP_InputField [] inputFields;

void Update() {
    foreach (var input in inputFields) {
        if (input.isFocused) Debug.Log(input.name);
    }
}

```

If you tested it with a button click, the Inputfield is not anymore focused. If you have a different problem, please add your code as well.

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


# Question
Title: How to project a Vector3 onto the xz plane?
I have this code that tries to check whether a lobbed grenade will head toward a teammate:

```
    var heading = tmPosition - grenadePos;
    var distance = heading.magnitude;
    var normalizedDir = heading / distance;

    if (Vector3.Dot(heading, (grenadePos + grenadeVelocity)) < 1.05f && Vector3.Dot(heading, (grenadePos + grenadeVelocity)) > 0.95f)
    {
        return true;
    }

```

`tmPosition` is the position of my teammate. The grenade can be lobbed for long distances or thrown like a baseball (with a slightly arcing trajectory) for closer range so my teacher says to project its trajectory as well as the `heading` vector on to the ground xz plane to make sure that my code above that predicts whether a particular grenade is heading towards my teammate or not.

How do I do this? I saw the API for `Vector3.Project` and `Vector3.ProjectOnPlane` but the examples are not very good.

# Answer
You can 0-out the Y coordinate. This is called an orthographic projection:

```
Original vector:                    (1, 2, 3)
Ortographic projection on XZ plane: (1, 0, 3)

```
> 4 votes

---
Tags: unity, vector, linear-algebra, projection, projectile
---


title: How to run a Haxe project?

text:
# Question
Title: How to run a Haxe project?
I'm new to using Haxe, and I'm trying to learn from this open source project

I recently watched the tutorial video "introduction to Haxe helloworld" and they didn't use any `.hxml` file to compile.

If I look in `canaanreborn2020prealha > game-master`, there are several files, including a `compile.hxml`.

I know that I have to do something with it right? What are the exact steps?

# Answer
An HXML file is a format which stores a list of compiler arguments. It can have any name (not just `build.hxml`) as long as it has the `.hxml` extension, and a project can have multiple `.hxml` files (which is useful for distinguishing between targets for example).

In your example, you can call the following from the command line to build the Haxe project:

```
haxe compile.hxml

```
> 1 votes

# Answer
You should point hxml file to haxe to compile it.
> 0 votes

---
Tags: haxe
---


# Question
Title: Copying transforms from one object to another
I am working on a virtual production app, and I need to be able to copy the transforms of one GameObject and all of its children to another. I asked previously here how to animate a character moving while allowing outside motion to override it, and it was suggested that I make a hidden copy of the character and transfer the positions of the bones to the main character in LateUpdate. Is there a way to copy all of the bone positions from one GameObject to another?

# Answer
> 0 votes
Something like this?

```
public static void CopyTransformTree(Transform sourceRoot, Transform destRoot) {
    // Read local pose in one operation.
    sourceRoot.GetLocalPositionAndRotation(out var localPos, out var localRot);
    // Clone local pose to destination transform in one operation.
    destRoot.SetLocalPositionAndRotation(localPos, localRot);

    // Clone scale (skip if your bones don't use scale).
    destRoot.localScale = sourceRoot.localScale;

    // Iterate over as many children as both roots have.
    int limit = Mathf.Min(sourceRoot.childCount, destRoot.childCount);
    for (int i = 0; i < limit; i++) // Recurse on each child sub-tree.
        CopyTransformTree(sourceRoot.GetChild(i), destRoot.GetChild(i));
}

void LateUpdate() {
    CopyTransformTree(sourceRootBone, destRootBone);
}

```

# Answer
> 0 votes
You can copy the transforms of one GameObject and all of its children to another using the Transform class's methods.

public void CopyTransforms(Transform sourceTransform, Transform targetTransform)
{
    // Copy the position, rotation, and scale of the source transform to the target transform
    targetTransform.position = sourceTransform.position;
    targetTransform.rotation = sourceTransform.rotation;
    targetTransform.localScale = sourceTransform.localScale;

    // Copy the positions, rotations, and scales of all child transforms recursively
    foreach (Transform sourceChild in sourceTransform)
    {
        Transform targetChild = targetTransform.Find(sourceChild.name);
        if (targetChild)
        {
            CopyTransforms(sourceChild, targetChild);
        }
    }
}
```

---
Tags: unity, animation
---


# Question
Title: How can you subscribe to Unity input events, instead of polling for them
Been trying for days to figure out if there is a way to subscribe to keyboard/mouse events in unity. Instead of having to poll for them every frame and make my own events.

Right now I poll through the inputs and fire off my own events if a button is pressed. I'd prefer to subscribe directly to Unities input events, but have yet to figure out how.

I have a Unity Answers post that may have some relevant info to my question as well: http://answers.unity3d.com/questions/878485/is-there-a-more-efficient-way-to-make-events-for-k.html

# Answer
> 6 votes
There's no built-in way to do that. If you prefer an event based solution you can wrap all input polling inside a component and expose the relative and subscribe for them.

Some like:

```
public EventHandler : MonoBehaviour
{
  public event Action<Vector2> mouseCliked;

  void Update()
  {
    if (Input.GetMouseButtonDown(0))
    {
      mouseCliked(mousePosition);
    }
    ....
  }
}

```

# Answer
> 3 votes
If you want an event-based input handling in modern Unity, then you might want to use the new input system. While it *can* be used in a polling manner like the classic Input system, it is designed to be used in an event-based manner. There are in fact *four different ways* to use it in an event-based manner:

* PlayerInput component with **SendMessage**, which will use the Unity messaging system and call methods on the same gameObject based on the name of the method. For example, when you have an input action "Jump", it will call any method named `OnJump`.
* PlayerInput component with **InvokeUnityEvents**, which will allow you to set any methods of any object as event handlers in the inspector or the component.
* Define variables in your script of type `InputAction`, which you either set via inspector or by finding the action by name via the public methods of an InputAction asset. Then subscribe to the `.performed` C# event of those input actions.
* Auto-generate a C# class from the InputActions asset. You can then instantiate that class from a script and programmatically set up event subscriptions for the C# events it provides for all the input actions.

The new input system also offers a ton of other benefits over the classic one. Like more consistent handling of different kinds of gamepads, binding keyboard keys by location instead of letter and abstracting away lots of different input devices as consistent semantic input actions.

# Answer
> 2 votes
As said by Heisenbug is no built-in way to do this.

My recommendation is to explore the UnityEvent namespace new to Unity 4.6 and above. This will allow you to expose functionality to designers that will allow them to rig up interesting inputs and receivers.

You can go the extra mile and implement a custom editor with a serialized dictionary and button to add new listeners.

Edit: If you need to describe you could go with the dreaded singleton and process subscription requests to provide KeyCodes and press types.

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


# Question
Title: How do I ensure that an enemy has a maximum of 3 attackers on him?
I'm coding the combat system for my RTS game, and every time a unit spawns I iterate over all enemies and then attack the closest one. This is achieved using the below block of code:

```
void FindCurrentTarget()
    {
        //find all potential targets (enemies of this character)
        enemies = GameObject.FindGameObjectsWithTag(attackTag);

        //distance between character and its nearest enemy
        float closestDistance = Mathf.Infinity;
        GameObject potentialTarget = null;
        foreach (GameObject _enemy in enemies)
        {
            //check if there are enemies left to attack and check per enemy if its closest to this character
            if (Vector3.Distance(transform.position, _enemy.transform.position) < closestDistance && _enemy != null)
            {
                //if this enemy is closest to character, set closest distance to distance between character and enemy
                closestDistance = Vector3.Distance(transform.position, _enemy.transform.position);

                //also set current target to closest target (this enemy)
                if ((currentTarget == null) || ((currentTarget != null) && Vector3.Distance(transform.position, currentTarget.transform.position) > 2))
                {
                    potentialTarget = _enemy;
                }
            }
        }
        //set the current target at end of for loop, this is the closest enemy
        currentTarget = potentialTarget;

    }

```

This works as expected but the problem is that if I deploy 10 units, all 10 units will target the same closest unit and will gang up on the poor guy. These 10 units will then all move to the next guy and this way I have a murder ball of units.

I am thinking of a solution for this but cant think of any, any ideas as a solution would be greatly welcomed.

One solution I thought was to ensure that a target can have a maximum of 3 attackers, and if in the above loop, if it is seen that a target already has 3 attackers attacking it then move on to the next.

For this I added an `int _attackers` to the `Character()` script, and then when a new target is found it increments that integer, and if that integer is 3 we move on to the next enemy in the loop.

Below is the modification of the above code to take into account max attackers:

```
void FindCurrentTarget()
    {
        //find all potential targets (enemies of this character)
        enemies = GameObject.FindGameObjectsWithTag(attackTag);

        //distance between character and its nearest enemy
        float closestDistance = Mathf.Infinity;
        GameObject potentialTarget = null;
        foreach (GameObject _enemy in enemies)
        {
            // if the current enemy already has 3 attackers on him, then ignore and move to next
            if (_enemy.GetComponent<Character>()._attackers >= 3)
                continue;

            //check if there are enemies left to attack and check per enemy if its closest to this character
            if (Vector3.Distance(transform.position, _enemy.transform.position) < closestDistance && _enemy != null)
            {
                //if this enemy is closest to character, set closest distance to distance between character and enemy
                closestDistance = Vector3.Distance(transform.position, _enemy.transform.position);

                //also set current target to closest target (this enemy)
                if ((currentTarget == null) || ((currentTarget != null) && Vector3.Distance(transform.position, currentTarget.transform.position) > 2))
                {
                    potentialTarget = _enemy;
                }
            }
        }
        // in case we have a different target than the one we are changing to then decrement attacker before changing target
        if (currentTarget != null && potentialTarget != null && potentialTarget != currentTarget)
        {
            potentialTarget.GetComponent<Character>()._attackers--;
        }
        // increment the attacker after targetting it
        if (potentialTarget != null)
        {
            potentialTarget.GetComponent<Character>()._attackers++;
        }

        //set the current target at end of for loop, this is the closest enemy
        currentTarget = potentialTarget;

    }

```

I am of course also ensuring that the int is decremented when the attacker dies and and am also clamping the value of `_attackers` between 0 and 4.

But this modification is not working, the nearest enemies are ignored, the targeting which used to be nearest first is now random, sometimes targets are ignored entirely.

When I check in the inspector the targets that are ignored, it shows that the `_attackers` variable is already at 3. When I debug which of my deployed units is these 3 units, its just a random selection, no longer is the nearest principle respected.

Ive tried all day trying to fix this and I just end up fixing one thing and breaking two. It should be a simple enough concept to implement, but its apparently not :(

# Answer
You have this in your code:

```
// in case we have a different target than the one we are changing to then decrement attacker before changing target
if (currentTarget != null && potentialTarget != null && potentialTarget != currentTarget) {
    potentialTarget.GetComponent<Character>()._attackers--;
}
// increment the attacker after targetting it
if (potentialTarget != null) {
    potentialTarget.GetComponent<Character>()._attackers++;
}

```

You are decrementing the number of attackers on `potentialTarget` by 1 and then incrementing it by 1; the net result is no change.

Perhaps you meant:

```
// in case we have a different target than the one we are changing to then decrement attacker before changing target
if (currentTarget != null && potentialTarget != null && potentialTarget != currentTarget) {
    currentTarget.GetComponent<Character>()._attackers--; //currentTarget instead of potentialTarget
}

```

For better performance, you should try to avoid `FindGameObjectsWithTag()` and `GetComponent()` as much as possible. It's hard to suggest a specific approach without having a better understanding of how you're using tags, but one possible approach is to search by type:

```
Character[] characters = GameObject.FindObjectsOfType<Character>();

```

However, if both allies and enemies can be characters, the array will include units you don't want to look at. Another potential solution is to create a component that is used to track the units that belong to a faction.
> 1 votes

# Answer
The classic solution is to issue "attacker tokens".

\<\< Before each attack, enemies must acquire a token for it. After the attack and some cooldown period, the token goes back into the “free” pool.

Changing the number of available tokens for each attack type and tweaking the cooldown periods are an easy way to adjust overall difficulty. \>\>

https://www.catnapgames.com/2022/08/21/d2-log-070-attack-tokens/

You can Loop through your enemies, and give the closest enemies an Attacker Token. Once they have that token, they can change their State from "Roam" to "Attack".

Then when an enemy is killed, the token can be returned to a Attacker Token Queue... and you can loop through the Queue, and assign the attack token to the closest enemy.
> 1 votes

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


# Question
Title: OnTriggerEnter2D and OnTriggerExit2D are firing each frame of a collision and OnTriggerStay2D never fires
So I'm basically making pong and lethal league combined, the paddles start with no collision until a certain key is pressed then the collider is enabled. OnTriggerEnter2D stops the ball, OnCollisionStay2D adds to an acceleration variable while the ball is still colliding, and OnTriggerExit2D flips the direction of the ball and applies the acceleration.

The problem I'm having right now is that Enter and Exit are being called every frame of the collision instead of the first frame and the frame after collision respectively, and Stay is never called at all, but that part is understandable.

Even if I comment out the OnTriggerExit2D function, which again applies the new speed and flips the direction, and essentially make the ball stop on collision, OnTriggerEnter2D will still fire each frame despite nothing moving.

I tried taking this to my professor but he wasn't of much help, I don't think I'll be able to get any help on this unless it's from here or I take my laptop to his office to show him what's going on. Please help

```
void OnTriggerStay2D(Collider2D c)
{
    if (c.gameObject.transform.tag.StartsWith("Paddle") && acceleration <= 1)
    {
        acceleration += 0.1f;
    }
}

void OnTriggerExit2D(Collider2D c)
{
    if (c.gameObject.CompareTag("PaddleLeft"))
    {
        dir.x = 1;
        speed = tempSpeed + acceleration;
    }

    if (c.gameObject.CompareTag("PaddleRight")
    {
        dir.x = -1;
        speed = tempSpeed + acceleration;
    }
}

void OnTriggerEnter2D(Collider2D c)
{
    if (c.gameObject.transform.tag.StartsWith("Paddle"))
    {
        tempSpeed = speed;
        speed = 0;
        acceleration = 0;
    }
 }

```

# Answer
> 0 votes
Always start by logging. If you try to infer which functions are being called based on the behavior you see in the game, you may misunderstand what is happening.

For example:

```
void OnTriggerStay2D(Collider2D c) {
    Debug.Log($"{this} OnTriggerStay2D N:{c.name} T:{c.tag}", this);
    if (c.gameObject.tag.StartsWith("Paddle") && acceleration <= 1) {
        acceleration += 0.1f;
    }
}

```

Then in the console, you'll see a message like

> `ball OnTriggerStay2D N:paddle T:PaddleLeft`

Adding a similar log message for each trigger function will help you understand exactly what is happening.

I don't think it will affect functionality, but for consistency, you should access the tag from the same place. Right now you do `c.gameObject.CompareTag()` in some places and `c.gameObject.transform.tag` in other places. You can simplify the latter to `c.gameObject.tag`, or simplify even further and use `c.tag` and `c.CompareTag()`.

# Answer
> 0 votes
My issue wasn’t the OnTrigger functions, aside from a few changes after the fix they behave as intended. My problem was actually cause from how I was enabling and disabling the colliders on the paddles. I was setting the colliders to false in the update function and then using Input.GetKey to detect if the key is pressed. So Unity thought it was a new collision each frame because it was. I fixed the issue by simply moving the lines of code that were disabling the colliders into else statements after the if statements containing the GetKey

---
Tags: unity, collision-detection
---


# Question
Title: How to access virtual camera's Aim Horizontal and Vertical Speed parameters through script?
I have a script that accesses the same thing but in freelook camera, but it doesn't work the same way with virtual camera apparently.

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

public class InventoryController : MonoBehaviour
{
    public GameObject inventory;
    public GameObject Button;
    public CinemachineFreeLook camera_ThirdPerson;
    public CinemachineVirtualCamera camera_FirstPerson;

    private bool isInventoryVisible;
    private bool isButtonVisible;

    void Start()
    {
        camera_ThirdPerson = GameObject.FindObjectOfType<CinemachineFreeLook>();
        camera_FirstPerson = GameObject.FindObjectOfType<CinemachineVirtualCamera>();
        isButtonVisible = true;
        isInventoryVisible = false;
        inventory.SetActive(isInventoryVisible);
        Button.SetActive(isButtonVisible);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            isInventoryVisible = !isInventoryVisible;
            inventory.SetActive(isInventoryVisible);
            UpdateCursorState();
            UpdateCameraState();
        }
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            isButtonVisible = !isButtonVisible;
            Button.SetActive(isButtonVisible);
            UpdateCursorState();
            UpdateCameraState();
        }
    }
    private void UpdateCursorState()
    {
        if (isInventoryVisible || isButtonVisible)
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;
        }
        else
        {
            Cursor.visible = false;
            Cursor.lockState = CursorLockMode.Locked;
        }
    }

    private void UpdateCameraState()
    {
        if (isInventoryVisible || isButtonVisible)
        {
            camera_ThirdPerson.m_XAxis.m_MaxSpeed = 0f;
            camera_ThirdPerson.m_YAxis.m_MaxSpeed = 0f;
        }
        else
        {
            camera_ThirdPerson.m_XAxis.m_MaxSpeed = 450f;
            camera_ThirdPerson.m_YAxis.m_MaxSpeed = 4f;
        }
    }
}

```

The `.m_YAxis.m_MaxSpeed` doesn't work with the virtual camera nor does `m_HorizontalAxis.m_MaxSpeed` nor `m_Horizontal.m_MaxSpeed`. I'm just trying to do the same thing I did with the freelook camera to the virtual camera.

# Answer
> 1 votes
```
var pov = vcam.GetCinemachineComponent<CinemachinePOV>()
pov.m_HorizontalAxis.m_MaxSpeed = 0;
pov.m_VerticalAxis.m_MaxSpeed = 0;

```

Unless you select the aim type POV, you cannot access any data related to speed because it does not exist.

---
Tags: unity, cinemachine
---


# Question
Title: Re-coloring PNG images with an indexed palette
I'm creating some images for an existing game that allows for custom content. I have a large collection of PNG images with indexed colors (all using the same palette). I would like to be able to go through these images and selectively paint over parts of them in such a way that it replaces the old color with a new color, but only with a certain range of the palette. The last 12 orange colors in the palette are special indices, and I want to use them in certain parts of the graphics.

For example, I would brush over this image to replace the colors with the closest match only from the 12 orange colors at the end of the palette (this tree was originally all green, but I want to paint its leaves the orange color, leaving the trunk alone, just as an example):

However I'm having a really difficult time finding tooling that will do this exactly, while supporting indexed mode and ensuring that the resulting area I paint only uses the colors from certain indices.

I have a lot of images to adjust, so I'd prefer a tool that lets me just open an image, brush it, save, and get out.

Some things I've tried so far:

* Photoshop: Doesn't like doing color replace with indexed images; you can convert to RGB mode and back, but there is no guarantee that the orange bits of the resulting image will be the correct ones, since there are other oranges in the palette that are pretty close.
* Gimp: Actually does color replacement in indexed mode with a brush, but also doesn't guarantee that the colors I get back are the right ones for the same reason.
* Aseprite: Has some promising scripting options, but doesn't seem to support this kind of custom brushing, and would only do the entire image, which is undesirable.
* Paint.NET: Doesn't even know what indexed palettes are, as far as I know.

I'm running out of options that I can think of aside from literally writing my own software to do this, which I'd like to avoid... are there other tools out there that can do what I need? Or functionality in the tools I've tried that I've missed?

# Answer
> 1 votes
If you know which colors you want to map to which, wouldn't a script work better than a brush? It would seem it's not a spatial targeting issue (what a brush would solve) but rather a color targeting issue.

If you're up for compiling and running a Java program, then this will let you map same-length index ranges from one to another. I chose Java because in C# (my first choice) there were issues with both `System.Drawing.Bitmap` and `Eto.Drawing.Bitmap` in console apps, and because the Aseprite trial version doesn't allow me to try the scripting feature before buying.

If you still need to use a brush, you can import both images as layers in your preferred software, and just use the eraser tool on one.

```
import javax.imageio.ImageIO;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class MapIndexedColoredImage {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        // Read in user-specified file.
        BufferedImage image;
        while (true) {
            System.out.print("Enter image filename: ");
            String filename = input.nextLine();
            File file = new File(filename);

            if (!file.exists()) {
                System.out.println("Could not find file!");
                continue;
            }

            try {
                image = ImageIO.read(new File(filename));
            } catch (IOException e) {
                System.out.println("Could not open file for some reason!");
                continue;
            }

            // Make sure it's indexed-colored.
            if (image.getType() != BufferedImage.TYPE_BYTE_INDEXED) {
                System.out.println("Image does not seem to be indexed-colored!");
                continue;
            }

            break;
        }

        // Get a handle on it (and make a copy of its data the way that seemed to work).
        DataBuffer imageDataBuffer = image.getRaster().getDataBuffer();
        int[] imageDataBufferElementsCopy = new int[imageDataBuffer.getSize()];
        for (int i = 0; i < imageDataBuffer.getSize(); i++) {
            imageDataBufferElementsCopy[i] = imageDataBuffer.getElem(i);
        }

        while (true) {

            // Get the translation range start or the save file name.
            int mappingSourceStart;
            while (true) {
                System.out.print("First color index in span to translate from, range [0,255], or filename to save image as: ");
                String token = input.nextLine();
                try {
                    mappingSourceStart = Integer.parseInt(token);
                } catch (NumberFormatException e) {

                    // Not a number => treat it as a filename. Save and return from program main function.
                    try {
                        ImageIO.write(image, "png", new File(token));
                    } catch (IOException e2) {
                        System.out.println("Could not write file for some reason!");
                        continue;
                    }
                    return;

                }
                if (mappingSourceStart < 0 || mappingSourceStart > 0xFF) {
                    System.out.println("Please enter an integer range 0-255!");
                    continue;
                }
                break;
            }

            int mappingSourceEnd = acceptInteger255OrBlank(input,
                    "Last color index in span to translate from, range [0,255]; blank for single color: ");
            if (mappingSourceEnd < 0) {
                mappingSourceEnd = mappingSourceStart;
            }

            int mappingDestinationStart = acceptInteger255OrBlank(input,
                    "First color index in span to translate to, range [0,255]; blank to correct above: ");
            if (mappingDestinationStart < 0) {
                continue;
            }

            System.out.println("Mapping colors [" + mappingSourceStart + ", " + mappingSourceEnd + "] to [" +
                    mappingDestinationStart + ", " + ((mappingSourceEnd - mappingSourceStart + mappingDestinationStart) & 0xFF) + "]...");
            if (mappingSourceEnd < mappingSourceStart) {
                mappingSourceEnd += 0x100; // handles wrap-around ranges (part 1)
            }
            for (int i = 0; i < imageDataBuffer.getSize(); i++) {
                int colorIndex = imageDataBufferElementsCopy[i];
                if ((colorIndex >= mappingSourceStart && colorIndex <= mappingSourceEnd) ||
                        colorIndex <= mappingSourceEnd - 0x100) { // handles wrap-around ranges (part 2)
                    colorIndex = (mappingDestinationStart - mappingSourceStart + colorIndex) & 0xFF;
                    imageDataBuffer.setElem(i, colorIndex);
                }
            }
        }
    }

    private static int acceptInteger255OrBlank(Scanner input, String text) {
        int value;
        while (true) {
            System.out.print(text);
            String token = input.nextLine();
            if ("".equals(token)) {
                return -1;
            }
            try {
                value = Integer.parseInt(token);
            } catch (NumberFormatException e) {
                System.out.println("Please enter an integer or blank!");
                continue;
            }
            if (value < 0 || value > 0xFF) {
                System.out.println("Please enter an integer range 0-255!");
                continue;
            }
            break;
        }
        return value;
    }
}

```

```
Enter image filename: test.png
First color index in span to translate from, range [0,255], or filename to save image as: 96
Last color index in span to translate from, range [0,255]; blank for single color: 107
First color index in span to translate to, range [0,255]; blank to correct above: 243
Mapping colors [96, 107] to [243, 254]...
First color index in span to translate from, range [0,255], or filename to save image as: test2.png

```

---
Tags: png, palette
---


title: DirectX 9 D3DFVF_XYZRHW and texturing

text:
# Question
Title: DirectX 9 D3DFVF_XYZRHW and texturing
This code is DirectX 9, software rendering. I have next piece of code to simple draw textured cube (see below). Cube geometry draws correctly, but texturing is affine - with distortions (my cube is rotate). How to apply perspective correct texturemapping in my sample? I wrote same code in DirectX 6 and it works perfectly - with perspective correnct texturemapping. Whats wrong in my DX9 sample?

```
struct MY_VERTEX
{
    D3DXVECTOR4 p;
    D3DXVECTOR2 t;

    static const DWORD FVF;
};

const DWORD MY_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;

void Render_Scene()
{

//...........................

//cube model has 24 vertices with tex coords
for ( int i = 0; i < 24; i++ )
{
    MY_VERTEX v1;
    MY_VERTEX v2;

    D3DXVec4Transform(&v1.p, &vert_buff[i].p, &MxRotateY);
    D3DXVec4Transform(&v2.p, &v1.p, &MxWorld);
    D3DXVec4Transform(&v1.p, &v2.p, &MxProj);

    v1.p.x = v1.p.x / v1.p.w;
    v1.p.y = v1.p.y / v1.p.w;

    v1.p.x = v1.p.x * rc.right / 2.0f + rc.right / 2.0f;
    v1.p.y = -v1.p.y * rc.bottom / 2.0f + rc.bottom / 2.0f;

    v1.t.x = vert_buff[i].t.x;
    v1.t.y = vert_buff[i].t.y;

    vert_buff_transformed[i] = v1;
}

HRESULT hr;

hr = p_d3d_Device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 60, 100, 150), 1.0f, 0 );
if(FAILED(hr)) return;

hr = p_d3d_Device->BeginScene();
if(FAILED(hr)) return;

p_d3d_Device->SetTexture(0, g_pTexture);

p_d3d_Device->SetFVF( MY_VERTEX::FVF );

p_d3d_Device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,0,24,12, index_buff,D3DFMT_INDEX16, vert_buff_transformed, sizeof(MY_VERTEX));

hr = p_d3d_Device->EndScene();
if(FAILED(hr)) return;

hr = p_d3d_Device->Present( NULL, NULL, NULL, NULL );
if(FAILED(hr)) return;

}

```

# Answer
> 1 votes
I did put some additional lines in loop and it works fine:

```
v1.p.x = v1.p.x / v1.p.w;
v1.p.y = v1.p.y / v1.p.w;
v1.p.z = v1.p.z / v1.p.w;    //added
v1.p.w = 1.0f / v1.p.w;      //added

```

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


# Question
Title: How to move camera by "grabbing" ground and moving mouse
I want to grab my terrain and move the camera with my mouse, this was fairly simple to do using speed:

Code (CSharp):

```
newPosition = transform.position; //Set in Start
//...

// In update
newPosition -= new Vector3(Input.GetAxis("Mouse X") * cameraDragSpeed, 0, Input.GetAxis("Mouse Y") * cameraDragSpeed);
transform.position = Vector3.Lerp(transform.position, newPosition, GameManager.Instance.GetNormalizedTimescale() * acceleration);

```

But I dont want to use speed, I want to use the difference between the drag origin (or the last drag position) and the new drag position.

I got some code running that oddly work "kind of" well, but has periods where it starts acting rly strangly, like the camera will keep panning while I hold down my button, even tho im not moving the mouse. But it happens very randomly. Or sometimes the drag speed is really responsive but other times its like im dragging in mud.

Code (CSharp):

```
// In update
// Drag movement
            if (Input.GetMouseButtonDown(1))
            {
                cameraMovementDragOrigin = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
            }
            else if (Input.GetMouseButton(1))
            {
                var diff = cameraMovementDragOrigin - new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
                newPosition += new Vector3(diff.x, 0, diff.y);
                transform.position = newPosition;
                return;
            }

```

Can someone spot what im doing wrong?

# Answer
> 1 votes
This should help you out. Put it on the camera.

```
using System;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CameraDragMove : MonoBehaviour
{
    [SerializeField] private float sensitivity = 1f;
    [SerializeField] private float lerpT = 0.5f;

    private Camera _camera;

    private Vector3 _initialMousePosOnXZPlane = Vector3.zero;
    private Vector3 _initialCameraPos = Vector3.zero;
    private Vector3 _desiredPos = Vector3.zero;

    private void Start()
    {
        _camera = GetComponent<Camera>();
        _desiredPos = transform.position;
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            _desiredPos = transform.position;
            _initialCameraPos = transform.position;
            _initialMousePosOnXZPlane = GetMousePositionOnXZPlane();
        }
        else if (Input.GetMouseButton(1))
        {
            var mouseDeltaOnXZPlane = _initialMousePosOnXZPlane - GetMousePositionOnXZPlane();
            _desiredPos = _initialCameraPos + mouseDeltaOnXZPlane * sensitivity;
        }
    }

    private void LateUpdate()
    {
        transform.position = Vector3.Lerp(transform.position, _desiredPos, lerpT);
    }

    private Vector3 GetMousePositionOnXZPlane()
    {
        return GetScreenPointOnPlane(Vector3.up, Vector3.zero, Input.mousePosition);
    }

    private Vector3 GetScreenPointOnPlane(Vector3 planeNormal, Vector3 planeOrigin, Vector3 screenPoint)
    {
        var plane = new Plane(planeNormal, planeOrigin);
        var mouseRay = _camera.ScreenPointToRay(screenPoint);
        if (plane.Raycast(mouseRay, out var hitDistance))
        {
            return mouseRay.GetPoint(hitDistance);
        }

        throw new Exception("Invalid raycast");
    }
}

```

Here is a diagram that explains what this script is doing:

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


# Question
Title: Switching a velocity from one rigid body to another in unity
I have a set up where the ground and the player move with physics and a stationary camera.

I want the ground to move faster when the player is getting further away making it look that the player is moving faster without getting further away from the camera.

The way I first thought was to just add the player velocity to the ground velocity, since velocity doesn't care about mass, and set the player velocity to 0.

*On the player script:*

```
    public void MovePlayer(Vector3 force)
    {
        rb.AddForce(force, ForceMode.Force);
    }

    private void FixedUpdate()
    {
        if (rb.position.z > 10)
        {
            PlatformManager.PlayerVelocity = rb.velocity.z;
            rb.velocity = new Vector3(rb.velocity.x, rb.velocity.y, 0);
        }
        else
        {
            PlatformManager.PlayerVelocity = 0;
        }
    }

```

*On the ground script:*

```
      //On the fixed update
            if (playerVelocity > 0)
            {
                rb.velocity = (Vector3.back * speedMultiplier) - new Vector3(0, 0, playerVelocity);
            }
            else
            {
                rb.velocity = Vector3.back * speedMultiplier;
            }

```

Although this way the player stops at the set limit, because in the next frame its velocity is 0 and the ground velocity is back to regular.

So how could I achieve this? Do I need to calculate manually the velocity that would result in the player movement (with the force in `MovePlayer`) and set it to the ground? I can't use the force on the ground due to its mass difference.

# Answer
Assuming that DMGregory's guess that you're making an endless runner is correct, your question suddenly makes sense and is answerable.

I think you are going about this the wrong way. Currently, you are moving the player with forces, but want a way to transfer the velocity from the player to the ground. As you've already discovered, this is somewhat of a headache.

I'd suggest not using forces for this, and controlling velocity manually. You would track the player's current speed separately from the physics engine. Then, you could offset the player on the Z-axis based on the current speed.

```
public class Player : MonoBehavior {
    [SerializeField] private float currentSpeed;
    [SerializeField] private float speedToDistanceFactor = .1f;
    [SerializeField] private float maxDistance = 10f;
    [SerializeField] private float collisionSlowdownFactor = 1f;
    public float CurrentSpeed {
        get => currentSpeed;
        set {
            currentSpeed = Mathf.Max(value, 0); //don't allow negative speed
        }
    }

    //move us further away from the camera when we're going faster
    void Update() {
        var pos = transform.position;
        pos.z = CurrentSpeed * speedToDistanceFactor;
        pos.z = Mathf.Clamp(pos.z, 0, maxDistance);
        transform.position = pos;
    }

    //slow down when we collide with a GO tagged "Obstacle", based on
    //the mass of the object we hit.
    //you will probably need to change/customize this logic
    void OnCollisionEnter(Collision collision) {
        if (collision.gameObject.CompareTag("Obstacle")) {
            CurrentSpeed -= collision.body.mass * collisionSlowdownFactor;
        }
    }
}

```

Notice the `OnCollisionEnter()` function includes some basic logic for slowing the player down when they collide with an object. You can customize or replace this logic as needed.

Then the ground would move according to the current speed, for example:

```
public class Ground : MonoBehavior {
    [SerializeField] private Player player;
    [SerializeField] private Rigidbody body;

    void Awake() { Assert.IsNotNull(player); }

    void FixedUpdate() {
        if (body != null) {
            body.velocity = new Vector3(0, 0, -player.CurrentSpeed);
        } else {
            transform.Translate(0, 0, -player.CurrentSpeed * Time.deltaTime);
        }
    }
}

```

With this simple approach, we have one key value - `player.CurrentSpeed`. The player's z-position, and the movement of the ground, are both derived from this value. It's very simple and doesn't require transferring velocity from one object to another under certain conditions.
> 0 votes

---
Tags: unity, physics, rigidbody
---


# Question
Title: How to get the name of a function added as a listener to a Button's onClick event?
If my button uses AddListener to subscribe a function to listen for clicks:

```
mybutton.onClick.AddListener(getNameFunction);

```

Is there a way to get the name of that listening function (i.e. "getNameFunction" in this example)?

I tried `onClick.GetPersistentMethodName(0)`, but it does not seem like the right way.

if i add funtcion in onclick list, .GetPersistentMethodName(0) will return the name

But it does not seem to return the correct result when the function was added using AddListener in the script (e.g. in Start())."

# Answer
The problem is, you are using the normal `AddListener` method when adding your function. Listeners that you add over the editor do not use `AddListener` but `AddPersistentListener`.

As you can already see from the name, it matches the `GetPersistentMethodName`. `GetPersistentEventCount` returns as well 0 for the normal AddListener. You need to change the way how you add it since it is not possible to do it exactly the same way. Luckily there is a tool helper class for it.

```
public Button button;

void Start() {
    UnityEventTools.AddPersistentListener(button.onClick, MyClickFunction);
}

public void MyClickFunction() {
    Debug.Log(button.onClick.GetPersistentMethodName(0));
}

```

UnityEventTools is in the UnityEditor namespace and can't be used in the compiled build. Depending on why and for what you need the method name and the option in the editor compared to the normal listener, where you actually include the `UnityEventTools.AddPersistentListener` will depend. But you can't leave it in `Start` for your compiled build.

Normal editor

Runtime:
> 2 votes

# Answer
I felt fancy and decided to answer the actual question. You can do that with some reflection:

```
using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;

public class GettingMethodNamesFromUnityEvent : MonoBehaviour
{
    public UnityEvent exampleEvent;

    void Start()
    {
        exampleEvent.AddListener(Foo);
        exampleEvent.AddListener(Bar);
        exampleEvent.AddListener(Baz);

        var mCalls = exampleEvent
            .GetType()
            .BaseType
            .GetField("m_Calls", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(exampleEvent);

        var mRuntimeCalls = mCalls
            .GetType()
            .GetField("m_RuntimeCalls", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(mCalls) as IList;

        var delegateField = mRuntimeCalls[0]
            .GetType()
            .GetField("Delegate", BindingFlags.NonPublic | BindingFlags.Instance);

        var methodNames = mRuntimeCalls
            .Cast<object>()
            .Select(runtimeCall => delegateField.GetValue(runtimeCall))
            .Cast<MulticastDelegate>()
            .SelectMany(mcDel => mcDel.GetInvocationList())
            .Select(del => del.Method.Name)
            .ToArray();

        Debug.Log(string.Join(", ", methodNames));
    }

    private void Foo()
    {
    }

    private void Bar()
    {
    }

    private void Baz()
    {
    }
}

```

Prints "Foo, Bar, Baz" as expected:

Please note that this is terrible code, and you should probably never ever use it.
> 3 votes

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


# Question
Title: How to set up a cross-platform game project that can install standalone or via Steam?
I'm thinking about developing a game. I want to make it cross-platform for Windows, Debian-based Linux and MAC (arm / x86) from the start, which will of course take a bit more time but it also helps to keep down the struggle to later integrate it to other platforms.

As I'm starting from scratch, the first consideration that comes to mind is how to install the game. Here are my requirements:

* The game should be installable via steam.
* The game should be installable independently (even though it needs steam to run eventually). But I want to provide an installer, package, whatever on my webpage for users to **download**.
* If using external libraries, they should be open source (so is the game).

My intention is to provide it in the most iconic way for each platform. In Windows and Mac this would probably be an installer, whereas on Debian this would probably be a package or an archive.

The question is: how can I set this up to maximize user convenience and allow for some customizability (e.g. I want to design the installer logos/banners etc. myself)?

# Answer
From what I understand, the main thing you are asking is, if you had a standalone game, how to package it and make it usable from different platforms/operating systems.

With that said, I assume you have a game that can compile to a standalone form, as in having an executable file, asset files, any external dependencies etc. Now it's time to prepare it for distribution on other platforms:

# Steam

Steam willy happily accept a `.zip` file that contains your standalone project. The only thing you'd have to do is then tell it what file to execute when a person clicks the `Play Game` button. Something like, execute `bin/mygame.exe` or `rungame.sh`. You can also optionally give command line arguments for a more customised experience. This is the same for all operating systems you mentioned.

You don't have to worry about how your project is installed there, as the Steam Client can take care of that for you.

I'm not sure if Steam would accept an actual custom installer, but I imagine that might be a bit more involved.

> The game should be installable independently (even though it needs steam to run eventually). But I want to provide an installer, package, whatever on my webpage for users to download.

When implementing the Steamworks SDK in your game, you can add some functionality that basically says, if the game was not launched through Steam, exit and run it through Steam instead. This can be done with the `SteamAPI_RestartAppIfNecessary` flag. This is unrelated to making a program installable, which I'll cover below.

# Independently installable

This method is a bit more involved, as it differs from platform to platform. There are tools out there to create installable packages for Windows, assuming you have a standalone project already compiled and working.

### Windows

If you are using CMake, you can use `CPack` and `NSIS` to generate a desktop installer, which is a file people can just double click to install your project in their windows machine. There's more information about it on CPack - NSIS generator.

You can then use the Window's `MSIX` tool to generate a Windows Universal compatible project, to potentially upload it to the Windows Store.

### Linux

For Linux, since your project is open source, you can use something like `makefile`, to allow users to compile and install your program manually. A usual approach is for users to run the following:

```
make
make install

```

To compile and install a project on their system. It's a very long discussion of how to implement this, possibly out of scope for this answer.

Using this method, you can then create packages for different Linux Distributions. Since you asked about debian, there's some information on Debian - Introduction to Debian Packaging.

Each distro has different ways of doing that, but for the most part you'd need to attach the `makefile` approach above to a file that tells Debian what your game is about, how to compile it etc.

### Mac

Unfortunately my experience there is limited, and I can't help too much. I know it's a Unix platform, and it's possible to use `makefile`s mentioned above, but I believe you need to use `XCode` to make something easily distributable and installable.

# Conclusion

> The question is: how can I set this up to maximize user convenience and allow for some customizability (e.g. I want to design the installer logos/banners etc. myself)?

For the most part following the steps above will set you up for allowing users to try your game with just a few clicks. To modify the installer, the process is different for each platform.

On Steam you can upload graphical assets that are displayed on different places of your game page.

On CMake, you can supply project icons, which are used when it generates an installer.
> 2 votes

---
Tags: c++, cross-platform, steam, installer
---


# Question
Title: Map arrays of game objects to values of an enum in Unity inspector
I want to have a serialized field with an array of game objects for each item in a global enum, like this:

```
public enum MyEnum
{
    Item1,
    Item2,
    Item3
}

```

And have a MonoBehaviour script present something like this in the inspector:

I can't find proper documentation or example to make this work.

# Answer
> 2 votes
Here's a generic version of the trick I showed in the comment above:

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

[System.Serializable]
public struct EnumMap<TKey, TValue> : IEnumerable<TValue> where TKey : System.Enum
{
    [Serializable]
    public struct Entry {
#if UNITY_EDITOR
        // This handles drawing the enum labels in the inspector,
        // without showing a human-editable field, or taking up memory in-build.
        [HideInInspector]
        public string name;
#endif
        public TValue value;
    }

    [SerializeField] Entry[] _map;

    // Handles error reporting if we somehow get bad enum values
    // (eg. from disc/network or faulty math that's cast to enum).
    static void Validate(TKey key) {
        Assert.IsTrue(System.Enum.IsDefined(typeof(TKey), key),
            $"Invalid {typeof(TKey).Name} value {key} used as an EnumMap key.");
    }

    static int GetIndex(TKey key) {
        Validate(key);
        // Don't worry about this cast - the compiler does the right thing when
        // it reifies the generic into a concrete type, so there's no boxing.
        return (int)(object)key;
    }

    // Provide
    public TValue this[TKey key] {
        get  {
            return _map[GetIndex(key)].value;
        }
        set {
            _map[GetIndex(key)].value = value;
        }
    }

    public void Initialize() {
        // Make a blank map from scratch.
        var names = System.Enum.GetNames(typeof(TKey));
        _map = new Entry[names.Length];
        for (int i = 0; i < names.Length; i++) {
            _map[i].name = names[i];
        }
    }

    /// <summary>
    /// Call this method in OnValidate() and Reset() when using this
    /// collection in a MonoBehaviour or ScriptableObject.
    /// This handles changes in the key enumeration type.
    /// </summary>
    public void TryRevise()
    {
        // Compiles to a no-op in player builds and should be elided.
#if UNITY_EDITOR
        if (_map == null) {
            Initialize();
            return;
        }

        // Scan enum names for changes that force data to be remapped.
        var names = System.Enum.GetNames(typeof(TKey));
        // TODO: also validate that names are unique, and use consecutive indices starting at zero?
        if (names.Length != _map.Length) {
            // Update if the number of enum members changed.
            RemapData(names);
        } else {
            // Update if any of the names of enum members
            // changed or re-odered.
            for (int i = 0; i < names.Length; i++) {
                if (names[i] != _map[i].name) {
                    RemapData(names);
                    break;
                }
            }
        }
#endif
    }

#if UNITY_EDITOR
    // Editor-only container for unmapped data - gives an opportunity to recover
    // after accidentally leaving an old name unmapped.
    // TODO: use PropertyDrawer to show/manually delete orphaned data.
    [SerializeField, HideInInspector] List<Entry> _orphaned;

    // Used to track re-mapping from old names to new.
    [System.Flags]
    enum SlotStatus {
        Unmapped = 0,
        OldEntryMatchedFromHere = 1 << 0,
        NewEntryMatchedHere = 1 << 1,
        NewEntryDefault = 1 << 2
    }

    // Called when the enum has changed, to move data to the best-matched slots.
    void RemapData(string[] names) {
        // Make a fresh array to handle any changes in size/order
        // without unnecessary loss of data.
        var newMap = new Entry[names.Length];

        // Book-keeping to detect which old data has not been mapped.
        var slotStatus = new SlotStatus[Mathf.Max(newMap.Length, _map.Length)];
        int matches = 0;
        for (int i = 0; i < newMap.Length; i++) {
            Entry existingOrBlank;
            // Try to find existing data mapped to exactly the same enum value name.
            int matchIndex = Array.FindIndex(_map, item => item.name == names[i]);
            if (matchIndex >= 0) {
                // If we found it, insert it into the new map at its new index.
                existingOrBlank = _map[matchIndex];
                slotStatus[matchIndex] |= SlotStatus.OldEntryMatchedFromHere;
                slotStatus[i] |= SlotStatus.NewEntryMatchedHere;
                matches++;
            } else {
                // Otherwise, check if we saved it in the orphanded list.
                matchIndex = _orphaned.FindIndex(item => item.name == names[i]);
                if (matchIndex >= 0) {
                    existingOrBlank = _orphaned[matchIndex];
                    _orphaned.RemoveAt(matchIndex);
                    slotStatus[i] |= SlotStatus.NewEntryMatchedHere;
                } else {
                    // Final fallback: make a new, blank entry for the new name.
                    existingOrBlank = default;
                    existingOrBlank.name = names[i];
                    slotStatus[i] |= SlotStatus.NewEntryDefault;
                }
            }
            newMap[i] = existingOrBlank;
        }

        if (matches < _map.Length) {
            // If some old data was not remapped to new, go find it!
            for (int i = 0; i < _map.Length; i++) {
                if ((slotStatus[i] & SlotStatus.OldEntryMatchedFromHere) == 0) {
                    // If no old data was mapped to the same integer slot as this unmapped data,
                    // assume it was just renamed in-place and copy its data to the new name.
                    if (i < newMap.Length && slotStatus[i] == SlotStatus.NewEntryDefault)  {
                        Debug.LogWarning($"Unmapped enum value {i}: {_map[i].name} found - assuming it should map to new name {names[i]}.");
                        newMap[i] = _map[i];
                        newMap[i].name = names[i];
                    } else {
                        // Otherwise, we don't know where this data goes.
                        // Log an error that it's lost, for one of two reasons...
                        string problem = i < names.Length ? $"its slot has been mapped to {names[i]}" : "it's outside the range of the enum";
                        Debug.LogError($"Unmapped enum value {i}: {_map[i].name} found, but {problem}.");

                        // Cache unmaped data as an orphan.
                        string oldName = _map[i].name;
                        _orphaned.RemoveAll(item => item.name == oldName);
                        _orphaned.Add(_map[i]);
                    }
                }
            }
        }

        // Use the new map from now on.
        _map = newMap;
    }
#endif

    // Enabling use with ForEach:
    public struct Enumerator : IEnumerator<TValue> {
        Entry[] _map;
        int _index;

        public Enumerator(Entry[] map) {
            _map = map;
            _index = -1;
        }

        public bool MoveNext() {
            _index++;
            return _index < _map.Length;
        }

        public TValue Current => _map[_index].value;
        object IEnumerator.Current => Current;

        public void Reset() {
            _index = -1;
        }

        void IDisposable.Dispose() { }
    }

    public IEnumerator<TValue> GetEnumerator() => new Enumerator(_map);
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

```

You can use it like so:

```
public class MyScript : MonoBehaviour {

    [System.Serializable]
    EnumMap<MyEnum, GameObject[]> _enumMap;

    void Start() {
        // You can index it with an enum value...
        foreach(var gameObject in _enumMap[MyEnum.Item1]) {
            // Do something with each game object
            // in the "Item1" slot.
        }

        // Or iterate over all its contents:
        foreach(var array in _enumMap) {
            // Do something with the whole array of game objects
            // in each enum value slot.
        }
    }

    // These calls are needed to correctly set up the
    // array slots when the component is added / reset,
    // and update the data mapping after a change to the enum.
    void OnValidate() {
        _enumMap.TryRevise();
    }

    void Reset() {
        _enumMap.TryRevise();
    }
}

```

Pros with this approach:

* Automatically adjusts to changes in the enum values when loaded in the inspector or during a build.
* Enum values whose order has changed will remember their mapped payload value.
* Enum values that are renamed in-place will get mapped to their new names (with a warning in case that was not intended).
* Enum values that are removed will have their "orphaned" data saved and log an error. If you re-introduce that value name, the orphaned data will be restored into that slot.
* No extra editor scripts to write - works with default inspector.
* No class overhead (extra pointer indirection/heap allocation in build) or boxing. This compiles down to just a dense array of payload values indexed with an integer, about as lean as we could make it.

Cons with this approach:

* Need to remember to implement the `OnValidate()`/`Reset()` messages whenever you use one of these containers.
* Does not play nicely with enums that contain non-consecutive values, synonyms (multiple names mapped to the same value), or negative values.
* Outer list still shows the +- controls so it can be resized. The `OnValidate()` script will immediately set it back to the correct size, but if a user mistakenly shrinks the list, data payloads attached to the later items will be lost, since `OnValidate()` only sees the version of the array after it was shrunk.
* Has some overhead in editor, allocating enum name array on every change just to check if it's different now.
* While making small enum changes one at a time is safe, if one of your assets hasn't been opened for a while, there's no guarantee it will be able to remap all your data correctly and you might have to go hunting for the orphaned data to clean up.

A custom property drawer could make this a bit nicer - like giving an interface to view and re-map orphaned data.

---

Here are some other ways we could implement this to get rid of the requirement for `OnValidate` calls wherever this is used - maybe directions others could explore in their own answers:

* Make this a generic class instead and implement custom serialization via `ISerializationCallbackReceiver` to do what I'm doing above in `OnValidate`, without needing to add function calls to all scripts with such containers as members.

+ The downside with this is that now it's a reference type, so we've added some overhead: it gets a heap allocation separate from its contained array, so accessing an array entry is now two pointer hops instead of one. Its `OnAfterDeserialize()` also gets called in compiled builds, even though there can't be runtime changes to the enum to respond to, so this is unnecessary waste.

    Sadly, `ISerializationCallbackReceiver` does not work for value types like structs.
* Make an `[EnumMapped(typeof(TKey)]` attribute you can use to decorate a plain array of your payload type, then implement a custom property drawer that handles sizing and labelling the array entries to match the names of the enum `TKey`.

+ This is nice and lightweight, but it doesn't give any of the convenience of being able to edit the enum and have the data automatically re-map to match the updated definition or warn about mismatched data, so any enum changes have the potential to create bugs that are hard to find and fix manually.

    It also requires anything accessing the array to do the enum validation and conversion to `int` itself, since this is just a plain old array of values now, rather than being able to provide an enum-native interface with the error-checking centralized.
* Hybrid: define a generic `struct` like above, but use the property drawer to handle the data fix-ups on edit, instead of the serialization callbacks.

+ The downside with this is that the data fix-ups are invoked only when the field is drawn in the inspector. So if you have 200 prefabs or scriptable objects or game objects in different scenes using enum-mapped collections, you have to select every single one after an enum change to ensure their data has been re-serialized correctly. If you miss one, your next game build could have mismatched data, leading to *nightmare* bugs.

    Maybe there's a way to work around this with an editor script? But that might require scanning all assets for members using this type after any file change, which would bog down assembly reloads...

I feel like there has to be a more elegant solution that doesn't have the pain points of these, so I'd be curious what methods others can suggest in their own answers!

---
Tags: unity, c#, scripting, array
---


title: Swept AABB corners collisions

text:
# Question
Title: Swept AABB corners collisions
I'm working on a small SFML engine, and i'm trying to implement continuous collisions. It's working great, but the corners are getting detected as collisions and i can't figure out why. I already searched around a lot but couldn't find anything looking like my issue:

Video of the issue

```
    float Collider::sweptAABB(Collider &other, float dt, sf::Vector2f& normal)
{
    float xInvEntry, yInvEntry;
    float xInvExit, yInvExit;

    sf::Vector2f vel = m_velocity + (m_acceleration * dt);

    //if (!broadCheck(other, dt))
    //    return 1.0f;

    // find the distance between the objects on the near and far sides for both x and y
    if (vel.x > 0.0f) {
        xInvEntry = other.getTopLeft().x - (getTopLeft().x + getGlobalBounds().width);
        xInvExit = (other.getTopLeft().x + other.getGlobalBounds().width) - getTopLeft().x;
    } else {
        xInvEntry = (other.getTopLeft().x + other.getGlobalBounds().width) - getTopLeft().x;
        xInvExit = other.getTopLeft().x - (getTopLeft().x + getGlobalBounds().width);
    }

    if (vel.y > 0.0f) {
        yInvEntry = other.getTopLeft().y - (getTopLeft().y + getGlobalBounds().height);
        yInvExit = (other.getTopLeft().y + other.getGlobalBounds().height) - getTopLeft().y;
    } else {
        yInvEntry = (other.getTopLeft().y + other.getGlobalBounds().height) - getTopLeft().y;
        yInvExit = other.getTopLeft().y - (getTopLeft().y + getGlobalBounds().height);
    }

    // find time of collision and time of leaving for each axis (if statement is to prevent divide by zero)
    float xEntry, yEntry;
    float xExit, yExit;

    if (vel.x == 0.0f) {
        xEntry = -std::numeric_limits<float>::infinity();
        xExit = std::numeric_limits<float>::infinity();
    } else {
        xEntry = xInvEntry / vel.x;
        xExit = xInvExit / vel.x;
    }

    if (vel.y == 0.0f) {
        yEntry = -std::numeric_limits<float>::infinity();
        yExit = std::numeric_limits<float>::infinity();
    } else {
        yEntry = yInvEntry / vel.y;
        yExit = yInvExit / vel.y;
    }

    // find the earliest/latest times of collision
    float entryTime = std::max(xEntry, yEntry);
    float exitTime = std::min(xExit, yExit);

    // if there was no collision
    if (entryTime > exitTime || xEntry < 0.0f && yEntry < 0.0f || xEntry > 1.0f || yEntry > 1.0f) {
        normal = sf::Vector2f(0, 0);
        return 1.0f;
    } else {
        // calculate normal of collided surface
        if (xEntry > yEntry) {
            if (xInvEntry < 0.0f) {
                normal = sf::Vector2f(1.0f, 0.0f);
            } else {
                normal = sf::Vector2f(-1.0f, 0.0f);
            }
        } else {
            if (yInvEntry < 0.0f) {
                normal = sf::Vector2f(0.0f, 1.0f);
            } else {
                normal = sf::Vector2f(0.0f, -1.0f);
            }
        }

        // return the time of collision
        return entryTime;
    }
}

void Collider::resolveCollision(Collider &other, float dt)
{
    sf::Vector2f normal;
    float collisionTime = sweptAABB(other, dt, normal);
    sf::Vector2f vel = (m_velocity) + (m_acceleration * dt);

    if (collisionTime < 1.0f && math::length(vel) != 0.0f) {
        setFillColor(sf::Color(0, 255, 0, 50));
    } else {
        setFillColor(sf::Color(255, 0, 0, 50));
    }

    float remainingTime = 1.0f - collisionTime;
    if (collisionTime == 0) {
        float dotprod = (vel.x * normal.y + \
            vel.y * normal.x) * remainingTime;
        m_velocity.x = dotprod * normal.y;
        m_velocity.y = dotprod * normal.x;
        setPosition(getPosition() + (m_velocity));
    } else {
        m_velocity = vel;
        setPosition(getPosition() + m_velocity * collisionTime);
    }

    if (m_acceleration.x == 0 && m_acceleration.y == 0)
        m_velocity *= 0.95f;
    m_acceleration = sf::Vector2f(0, 0);

    m_sweptBox.setPosition(getTopLeft());
}

```

# Answer
> 0 votes
An AABB check is to determine an ***intersection*** of axis aligned bounding boxes, i.e., they there is some kind of overlap of those shapes.

Intersection is true **IF**: The projection of box A onto the X axis overlaps the projection of box B on the same axis **AND** The projection of box A onto the Y axis overlaps the projection of box B on the same axis.

This is your rudimentary check, which in code would simply return a boolean value (true/false).

Clearly, this is not very useful, so we need a little more information. This information comes in the form of an *intersection manifold*, and contains an edge normal, and a degree of penetration.

This is done by determining the axis of *least* penetration and retaining that value and axis, until all axes have been tested. (this is called Minimum traversal vector, or MTV)

By this point, you have your manifold, and it can be used to determine how to resolve the collision.

It is at this point your code your code gets a little weird:

You have interspersed various lines of code that interrogate and compute velocity. You do not need this unless you are trying to do physics based resolutions, which you are not. Your code would be better looking something like:

```
bool Collider::sweptAABB(Collider &other, float& penetration, sf::Vector2f& normal)
{
    // X axis projection
    float aXmin = getTopLeft().x;
    float aXmax = getTopRight().x;
    float bXmin = other.getTopLeft().x;
    float bXmax = other.getTopRight().x;
    // Y axis projection
    float aYmin = getTopLeft().y;
    float aYmax = getBottomLeft().y;
    float bYmin = other.getTopLeft().y;
    float bYmax = other.getBottomLeft().y;

    // Check for non-intersection and early exit clause.
    if (aXmin > bXmax) return false;
    if (bXmin > aXmax) return false;

    if (aYmin > bYmax) return false;
    if (bYmin > aYmax) return false;

    // If we reach this point, then there is a collision.
    // We now have to compute the manifold

    penetration = std::numeric_limits<float>::max();
    // Other collider on the right?
    if (bXmin < aXmax && aXmin < bXmax)
    {
        penetration = std::abs(bXmin - aXmax);
        normal = sf::Vector2f(-1.f, 0.f);
    }
    // Other collider on the left?
    if (aXmin < bXmax && bXmin < aXmax)
    {
        penetration = std::abs(aXmin - bXmax);
        normal = sf::Vector2f(1.f, 0.f);
    }
    // Repeat for Y axis
    // Other collider above?
    if (bYmin < aYmax && aYmin < bYmax)
    {
        float py = std::abs(bYmin - aYmax);
        if (py < penetration)
        {
            penetration = py;
            normal = sf::Vector2f(0.f, -1.f);
        }
    }
    // Other collider below?
    if (aXmin < bXmax && bXmin < aXmax)
    {
        py = std::abs(aXmin - bXmax);
        if (py < penetration)
        {
            penetration = py;
            normal = sf::Vector2f(0.f, 1.f);
        }
    }
    return true;
}

void Collider::resolveCollision(Collider &other)
{
    sf::Vector2f normal;
    float penetration = 0.0f;
    bool result = sweptAABB(other, penetration , normal);

    if (result) {
        setFillColor(sf::Color(0, 255, 0, 50));
        m_sweptBox.setPosition(getTopLeft() + normal * penetration);
    } else {
        setFillColor(sf::Color(255, 0, 0, 50));
    }
}

```

As you can see, you do not need dt, acceleration, or velocity for simple collision response, but if you wanted it to be more physics based, then you could compute the normal force, which is outside the scope of this question.

Now, to finally answer your question: The reason your box stops, is because you act on an intersection depth of **zero or greater**. Simply greater than zero is sufficient.

---
Tags: c++, collision-detection, sfml, aabb, collision-prediction
---


# Question
Title: Issue with rotating tail for 3d model in Maya
I've been stuck on this issue for a long time and it's been driving me crazy: I have this model of Jabba (see image 1) which I bought off of CG Trader several years back. I want the character to look exactly the same, but with the tail facing the opposite direction. Unfortunately, when I try to rotate the tail using the rotate tool from the base of the tail, the tail bends in a way where it doesn't look right (see image 2).

Here is a partial list of things I've tried:

* Rotating the spine instead of the tail
* Adding joints to the tail closer to the spine and rotating in a new axis of rotation
* painting skin weights for the joint and surrounding joints in every conceivable manner
* kind of fudging it using a tool called brsmoothweights
* messing with the attributes for tools to change rotational axes, position, etc.
* Recreating joints and re-rigging using IK handle

None of these techniques have solved the problem, the weird bending persists. I also tried mirroring the mesh (see image 3), which looks right on one side but it leaves a Jabba with 2 tails. I'm not confident enough in my modeling abilities to go in and try to edit the mesh by like deleting vertices and stuff.

It seems like there should be an easy fix to this problem, but I'm just not seeing it. Anyone out there have any advice? It would be greatly appreciated!

# Answer
> 0 votes
Not a Maya expert here, but it seems like the rig is messed up

---
Tags: 3d-meshes, maya, 3d-modeling, rigging
---