# Question
Title: Wall sliding in JavaScript; works, but gets stuck at corners
this is a follow up to this other question: How do I handle player collision with corners of a wall

In inspiration of the code given in its answer, I tried to write some new code.

Basically, in the original, the wall sliding works very well on the inside of the walls, but I wanted to make it work on the outside as well, so I made a new basic code engine, based on his technique:

```
BH
<br>
<meta charset="utf-8">
<button onclick="start()" class=wow>ok</button>
<canvas id=can>

</canvas>
<style>
    canvas{
        width:100%;
        height:100%;
        position:absolute;
        top:0;
        left:0px
    }

    .wow{
        float:right;
        z-index:1298737198
    }
</style>
<script>
    var aD =[]
    var r
    function start() {
        r = new CanvasRenderer(can),
            my = new scene();
        window.my = my
        eventHandler();

        my.add(new mesh({
            name:"ora",
            verts: [
                0,   0, //0,
                100, 15, //1,
                175, 40,
                50, 100,
                20, 75,
                2,25
            ],
            position: {
                x: 100,
                y:100,
                z:1
            },
            scale: {

                x:1,y:1,z:1
            },
            color:"orange",
            onupdate(me) {
                if(!me.dx) {
                    me.dx=0//.3
                }
                me.position.x+=me.dx

                me.position.y+=me.dx/3

                me.rotation.x+=me.dx*8*Math.PI/180

                if(me.position.x>=500) {
                    me.position.x--;
                    me.dx = -0.3
                }

                if(me.position.x<=0) {
                    me.position.x++
                    me.dx = 0.3
                }

            }
        }));

        my.add(new mesh({
            name:"tri",
            verts: [
                0,   0, //0,
                80, 35, //1,
                30, 70,
                28, 30,
                5, 80,
                4,  30
            ],
            position: {
                x: 100,
                y:200,
                z:1
            },
            rotation:{
                x:-20*Math.PI/180
            },
            scale: {

                x:2,y:2,z:1
            },
            color:"yellow",
            onupdate(me) {
                if(!me.dx) {
                    me.dx=0//-0.2
                }
                me.position.x+=me.dx

                me.position.y+=me.dx/3

                me.rotation.x+=me.dx*8*Math.PI/180

                if(me.position.x>=500) {
                    me.position.x--;
                    me.dx = -0.3
                }

                if(me.position.x<=0) {
                    me.position.x++
                    me.dx = 0.3
                }

            }
        }));

        var g = false
        my.add(new mesh({
            primitive:"rect",
            name: "player",
            scale: {
                x: 50,
                y:50
            },
            position: {
                x: 311,
                y:75,
                z:13
            },
            origin: {
                x:0.5,
                y:0.5,
                z:0.5
            },
            onupdate(me) {
                var upKey = keys[38],
                    downKey = keys[40],
                    rightKey = keys[39],
                    leftKey = keys[37],
                    drx  = 0,
                    dx = 0,
                    speed = 5,
                    turningSpeed = 3

                drx = leftKey ? -1 : rightKey ? 1 : 0
                forward = upKey ? 1 : downKey ? -1 : 0
                if(!window.aa)aa=me
                me.rotation.x += (
                    (drx * Math.PI / 180 * turningSpeed )
                )
                me.rotation.y = 1;

                var xDir = Math.cos(me.rotation.x)
                var yDir = Math.sin(me.rotation.x)

                me.position.x += xDir  * forward * speed
                me.position.y += yDir * forward * speed

                var lines = []
                for(var i = 0; i < my.objects.length; i++) {
                    let cur = my.objects[i];
                    if(cur.name !== me.name) {
                        cur.lineSegments.forEach(l => {
                            //if(lines.length>=2) return
                            var col = checkCollision(
                                me.position.x,
                                me.position.y,
                                me.position.z,
                                me.scale.x/2,
                                l
                            )

                            if(col) {

                                if(!me.curLine&&!col.iscorner)
                                    me.curLine = l
                            //  else
                                lines.push(l)

                            }
                         });
                    }
                }

                if(me.curLine) {
                    var oldL = lines.length
                    lines=insertAtArray(0,me.curLine,lines)
                    //remove duplicates

                    lines = uniq(lines)
                    /*

                    old code remove curr

                    lines.filter((v,ind,ar)=>
                        ar.indexOf(v)==ind
                    );
                    var sl = lines.slice(1)
                    var indo = sl.indexOf(me.curLine)
                    if(indo > -1)
                        lines.splice(indo,1)*/
                    //if(lines.length>=3) lines.splice(lines.length-1,1)
                }
                var fc = false
                lines.forEach(a=>{
                    var col = checkCollision(
                        me.position.x,
                        me.position.y,
                        me.position.z,
                        me.scale.x/2,
                        a
                    )
                    if(col) {
                        me.position.y = col.y
                        me.position.x = col.x
                        if(a==me.curLine)
                            fc=true
                    }

                })
                me.lines=lines
    //\
                if(!fc) me.curLine=null;

            }

        }));

        let i = setInterval(() => render(r, my), 16);
        r.on("resize", () => render(r, my));

    }

    function uniq(arr) {
        return arr.map(JSON.stringify)
            .filter(
                (el , i , arr)=>
                i === arr.indexOf(el)
            ).map(JSON.parse)
    }

    function insertAtArray(at,val,array) {
        return array = array.slice(0,at).concat(val)
                .concat(array.slice(at))
    }

    function checkCollision(x1, y1, z1, rad,l) {
        var dist = distance2(
            l.start[0],
            l.start[1],

            l.end[0],
            l.end[1]
        ),
            vec1 = [
                x1 - l.start[0],
                y1 - l.start[1],
                z1 - l.start[2]
            ],

            vec2 = [
                l.end[0] - l.start[0],
                l.end[1] - l.start[1]
            ],

            percentOfWall = (
                Math.max(
                    0,
                    Math.min(
                        1,
                        dot(
                            vec1[0],
                            vec1[1],

                            vec2[0],
                            vec2[1]
                        ) / dist
                    )
                )
            ),
            projection = [
                l.start[0] + percentOfWall * vec2[0],
                l.start[1] + percentOfWall * vec2[1],
            ],
            acDist = Math.sqrt(distance2(
                x1, y1,
                projection[0], projection[1]
            ))

        aD.push( () => {
            r.ctx.beginPath()
            r.ctx.fillStyle="green"
            r.ctx.arc(projection[0], projection[1], 5, 0, Math.PI*2);
            r.ctx.fill()
            r.ctx.closePath();
        })

        if(acDist < rad) {
            var mag = Math.sqrt(dist),
                delt = [
                    l.end[0] - l.start[0],
                    l.end[1] - l.start[1]
                ],
                normal = [
                    delt[0] / mag,
                    delt[1] / mag
                ]

            var x;
            var y;

            var iscorner=false
            if(
                percentOfWall == 0 ||
                percentOfWall == 1
                //case of corner[s]
             ) {

                var distFromProjToPlCenter = [
                    x1 - projection[0],
                    y1 - projection[1]
                ];

                var distNormalized = normalize(
                    distFromProjToPlCenter
                )

                var scaled = scaleVec(
                    distNormalized, rad
                )
                x = projection[0]+scaled[0]
                y = projection[1]+scaled[1]
                iscorner=true
            } else {
                x = projection[0] +
                    rad * (normal[1] )

                y = projection[1] +
                    rad* (-normal[0] )
            }

            return {
                x,
                y,
                projection,
                normal,
                iscorner
            }
        }

    }

    function scaleVec(vec,sc) {
        return [
            vec[0]*sc,
            vec[1]*sc
        ]
    }

    function dot(x1, y1, x2, y2) {
        return (
            x1 * x2 + y1 * y2
        )
    }

    function normalize(p) {
        var x = p[0]
        var y = p[1]
        //(x/(x^2 + y^2)^(1/2), y/(x^2 + y^2)^(1/2))
        var val = Math.sqrt(
            x * x +
            y * y
        )
        return [
            x / val,
            y / val
        ]
    }

    function distance2(x1, y1, x2, y2) {
        let dx = (x1 - x2), dy = (y1 - y2);
        return (
            dx * dx + dy * dy
        );
    }

    function render(r,s) {
    //r.ctx.clearRect(0,0,r.ctx.canvas.width,r.ctx.canvas.height)
        s.update();
        r.render(s)
        aD.forEach(x=>x());
        aD = []
    }

    onload = start;

    function eventHandler() {
        window.keys = {};
        addEventListener("keyup" , e=> {
            keys[e.keyCode] = false;

        });

        addEventListener("keydown" , e=> {
            keys[e.keyCode] = true;
        });
    }

    function CanvasRenderer(dom) {
        if(!dom) dom = document.createElement("canvas");

        var events = {}, self = this;
        function rsz() {
            dom.width = dom.clientWidth;
            dom.height = dom.clientHeight;
            self.dispatchEvent("resize");
        }

        window.addEventListener("resize", rsz);

        let ctx = dom.getContext("2d");

        function render(scene) {
            ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
            for(let i = 0; i < scene.objects.length; i++) {
                let o = scene.objects[i],
                    verts = o.realVerts;

                ctx.beginPath();
                ctx.moveTo(
                    verts[0] ,

                    verts[1]
                );
                verts.forEach((v, i, ar) => {
                    let y = i;

                    ctx.lineTo(
                        v[0] ,

                        v[1]
                    );

                });
                ctx.lineTo(
                    verts[0],
                    verts[1]
                );
                ctx.fillStyle = o.color || "blue";
                ctx.lineWidth = 1;
                ctx.fill()
                ctx.stroke();
                ctx.closePath();
            }
        }

        Object.defineProperties(this, {
            domElement: {
                get: () => dom
            },
            ctx: {
                get: () => ctx
            },
            render: {
                get: () => render
            },
            on: {
                get: () => (nm, cb) => {
                    if(!events[nm]) {
                        events[nm] = [];
                    }
                    events[nm].push(data => {
                        if(typeof cb == "function") {
                            cb(data);
                        }
                    });
                }
            },
            dispatchEvent: {
                get: () => (name, data) => {
                    if(events[name]) {
                        events[name].forEach(x => {
                            x(data);
                        });
                    }
                }
            }
        });

        rsz();

    }

    function scene() {
        let objects = [];
        Object.defineProperties(this, {
            add: {
                get: () => obj => {
                    objects.push(obj);
                }
            },
            objects: {
                get: () => objects
            },
            update: {
                get: () => () => {
                    objects.forEach(x => {
                        if(typeof x.update == "function") {
                            x.update();
                        }
                    });

                }
            }
        });
    }

    function mesh(data={}) {
        let verts = [],
            self = this,
            holder = {
                position:{},
                scale: {

                },
                rotation: {},
                origin:{}
            },
            actual = {

            },
            position = {},
            scale = {},
            rotation = {},
            origin = {},
            color,
            name,
            primitive,
            eventNames = "update",
            events = {},
            drawPrimitive = {
                circle(ctx) {
                    ctx.beginPath();
                    ctx.arc(
                        self.position.x,
                        self.position.y,
                        5,
                        0,
                        360 * Math.PI / 180
                    );
                    ctx.closePath();
                },
                rect(ctx) {
                    ctx.strokeRect(
                        self.position.x,
                        self.position.y,
                        30, 30
                    );
                }
            },
            width = 1,
            height = 1,
            primitiveToVerts = {
                rect: () =>  [
                        0, 0,
                        width , 0,
                        width, height,
                        0, height
                ]
            },
            realVerts = verts,
            lineSegments = [],
            o = this;

        function updateRealVerts() {

                let  actualVerts = [],
                    originedVerts = [],
                    adjustedVerts = [],
                    rotatedVerts = [],
                    stepSize = o.step || 2,
                    curVerts = [];

                o.verts.forEach((v, i) => {
                    curVerts.push(v);
                    if(
                        (i - 1) % stepSize === 0 &&
                        i !== 0
                    ) {
                        actualVerts.push(curVerts);
                        curVerts = [];
                    }
                });
                actualVerts = actualVerts.filter(x => x.length == stepSize);

                originedVerts = actualVerts.map(v => [
                    v[0] - o.origin.x,
                    v[1] - o.origin.y,
                    v[2] - o.origin.z
                ]);

                rotatedVerts = originedVerts.map(v =>
                    [

                        v[0] * Math.cos(o.rotation.x) -
                        v[1] * Math.sin(o.rotation.x),

                        v[0] * Math.sin(o.rotation.x) +
                        v[1] *Math.cos(o.rotation.x),
    v[2]
                    ]
                );

                adjustedVerts = rotatedVerts.map(v =>
                    [
                        v[0] *
                        o.scale.x +
                        o.position.x,

                        v[1] *
                        o.scale.y +
                        o.position.y,

                        v[2] *
                        o.scale.z +
                        o.position.z,
                    ]
                );

                realVerts = adjustedVerts;
                updateLineSegments();
        }

        function updateLineSegments() {
                    let lines = [];
                    for(let i = 0, a = realVerts; i < a.length;i++) {
                        let start = [], end = []
                        if(i < a.length - 1) {
                            start = a[i];
                            end = a[i + 1];
                        } else {
                            start = a[i];
                            end = a[0];
                        }

                        lines.push({
                            start, end,
                            goof:o.name
                        })
                    }
                    lineSegments = lines;
        }
        Object.defineProperties(position, {
            x: {
                get: () => holder.position.x || 0,
                set: v => holder.position.x = v
            },
            y: {
                get: () => holder.position.y || 0,
                set: v => holder.position.y = v
            },
            z: {
                get: () => holder.position.z || 0,
                set: v => holder.position.z = v
            }
        });

        Object.defineProperties(scale, {
            x: {
                get: () => holder.scale.x || 1,
                set: v => holder.scale.x = v
            },
            y: {
                get: () => holder.scale.y || 1,
                set: v => holder.scale.y = v
            },
            z: {
                get: () => holder.scale.z || 1,
                set: v => holder.scale.z = v
            }
        });

        Object.defineProperties(rotation, {
            x: {
                get: () => holder.rotation.x || 0,
                set: v => holder.rotation.x = v
            },
            y: {
                get: () => holder.rotation.y || 0,
                set: v => holder.rotation.y = v
            },
            z: {
                get: () => holder.rotation.z || 0,
                set: v => holder.rotation.z = v
            }
        });

        Object.defineProperties(origin, {
            x: {
                get: () => holder.origin.x || 0,
                set: v => holder.origin.x = v
            },
            y: {
                get: () => holder.origin.y || 0,
                set: v => holder.origin.y = v
            },
            z: {
                get: () => holder.origin.z || 0,
                set: v => holder.origin.z = v
            }
        });

        Object.defineProperties(this, {
            verts: {
                get: ()=>verts,
                set(v) {
                    verts = v
                }
            },
            name: {
                get: ()=>name,
                set(v) {
                    name = v
                }
            },
            primitive: {
                get: ()=>primitive,
                set(v) {
                    primitive = v;
                    let newVerts = primitiveToVerts[v];
                    if(newVerts) {
                        this.verts = newVerts();
                    }
                }
            },
            width: {
                get: ()=>width,
                set(v) {
                    width = v
                }
            },
            height: {
                get: ()=>height,
                set(v) {
                    height = v
                }
            },
            position: {
                get: () => position,
                set: v => {
                    position.x = v.x || 0;
                    position.y = v.y || 0;
                    position.z = v.z || 0;
                }
            },
            scale: {
                get: () => scale,
                set: v => {
                    scale.x = v.x || v.x === 0 ? v.x : 1;
                    scale.y = v.y  || v.y === 0 ? v.y : 1;
                    scale.z = v.z  || v.z === 0 ? v.z : 1;
                }
            },
            rotation: {
                get: () => rotation,
                set: v => {
                    rotation.x = v.x || 0;
                    rotation.y = v.y || 0;
                    rotation.z = v.z || 0;
                }
            },
            origin: {
                get: () => origin,
                set: v => {
                    origin.x = v.x || 0;
                    origin.y = v.y || 0;
                    origin.z = v.z || 0;
                }
            },
            color: {
                get: () => color,
                set: v => {
                    color = v;
                }
            },
            realVerts: {
                get: () => realVerts
            },
            lineSegments: {
                get: () => lineSegments
            },
            update: {
                get: () => () => {
                    if(events["update"]) {
                        events.update.forEach(x => {
                            updateRealVerts();
                            x(this);
                        });
                    }
                }
            },
            on: {
                get: () => (nm, fnc) => {
                    if(!events[nm]) events[nm] = [];
                    events[nm].push(stuff => {
                        if(typeof fnc == "function") {
                            fnc(stuff);
                        }
                    });
                }
            }
        });

        eventNames.split(" ").forEach(x => {
            var name = "on" + x;
            if(!this.hasOwnProperty(name)) {
                Object.defineProperty(this, name, {
                    get: () => events[name],
                    set(v) {
                        events[x] = [
                            data => {
                                typeof v == "function" && v(data)
                            }
                        ];
                    }
                });
            }
        });

        for(let k in data) {
            this[k] = data[k]
        }

        updateRealVerts();

    }
</script>
```

See "checkCollision" function and player loop for the relevant parts.

\[Edit\] It almost works as expected, but \[as you can see in the following gif\] it gets stuck only when caught between two objects, not sure why:

This version shows that the issue exists in any crevice, even within one object.

And either way if the angle is very small the player goes right through the corner:

Any ideas how to fix this -- without using any kind of external libraries etc. (only what's available in the snippet)?

# Answer
> 1 votes
You're not handling line endpoints correctly. Consider only a single line segment. The collision of a circle at the endpoint of a single line segment should be rounded, right? Like, if you trace out where the *center* of the circle should be stopped as you hit the endpoint from various angles, that will form a circle around the endpoint. Let's call this the player center's collision area. Now, you *are* correctly determining *when* the player's center has entered that area, but when it happens, you're using the same code to push the player away as you use when they hit the side of the line, which moves them to a point aligned with the line's endpoint, pushed out perpendicular to the line segment by the distance of their radius. This effectively pops them to the side of the line - to the same place regardless of where they touched the player center's collision area. If they've been sliding along the line segment and are trying to slide off the endpoint, this effectively pulls them back so they can't move forward (until they rotate to face totally away from the line). That's why you get stuck.

The solution is to change your collision resolution at the endpoints to push the player in the right direction: away from the endpoint. This is easy because you're already calculating the nearest point on the line and clamping it to the endpoints. So, instead of using the line's delta to calculate a normal vector to push them away, just take the direction from the closest point on the line ("projection" in your code) to the player's center ((x1,y1) - projection), normalize it and multiply that by the radius. This will always push them away, leaving them at the edge of the player's center collision area near where they entered it, so it won't pull them back as they try to round a corner. This will even work properly from both sides of the line segment.

# Answer
> 0 votes
I don't know much about javascript, but it seems like you are moving from pt1 to pt2 when you are colliding a wall. Notice that it depends what direction you are going. If you go on a wall and slide and block to the corner, when you go on the other wall sharing the same corner, you can slide and it will exit the wall, where on the other wall it was blocking. Now, if I get this right, you are sliding on the wall using pt1 to pt2, and it seems like depending on which corner is pt1 and which is pt2, you won't block on one of them. That means the order of the wall points changes something and somewhere you are saying that pt1 won't block and pt2 will block, or vice versa. If you understand any of this script, you should be able to fix this. Else, like the others said, you should try to understand it first, play around with it, than try to fix the problem.

---
Tags: 2d, collision-detection, javascript, collision-avoidance, collision-prediction
---


# Question
Title: How can I adjust this shader so that my atmospheric scattering works on spheres not positioned at the origin?
I have the following vertex and fragment shaders, adapted from this shader on shadertoy.

Vertex:

```
#version 330

layout (location = 0) in vec4 in_position;
layout (location = 1) in vec3 in_normal;
layout (location = 2) in vec3 in_UV;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

uniform vec3 cameraPosition;
uniform vec3 lightPosition;
uniform vec3 planetPosition;

out vec3 cameraPositionModel;
out vec3 lightPositionModel;
out vec3 positionModel;
out vec3 planetPositionModel;

void main()
{
    gl_Position = projection * view * model * vec4(in_position.xyz, 1.0);

    mat4 worldToModel = inverse(model);
    cameraPositionModel = vec3(worldToModel * vec4(cameraPosition, 1.0));
    lightPositionModel = vec3(worldToModel * vec4(lightPosition, 1.0));
    positionModel = in_position.xyz;//vec3(model * vec4(in_position.xyz, 1.0));
    planetPositionModel = vec3(worldToModel * vec4(planetPosition, 1.0));
}

```

Fragment:

```
#version 330

layout (location = 0) out vec4 color;

in vec3 cameraPositionModel;
in vec3 lightPositionModel;
in vec3 positionModel;
in vec3 planetPositionModel;

uniform float E = 14.3;
uniform float K_R = 0.166;
uniform float K_M = 0.0025;
uniform float G_M = -0.85;
uniform vec3 C_R = vec3(0.3, 0.7, 1.0);

uniform float innerRadius;
uniform float outerRadius;

const float PI = 3.14159265359;

const int numOutScatter = 10;
const float fNumOutScatter = 10.0;
const int numInScatter = 10;
const float fNumInScatter = 10.0;

vec3 ray_direction(vec3 cam)
{
    vec3 ray = positionModel - cam;
    return normalize(ray);
}

vec2 ray_sphere_intersect(vec3 rayOrigin, vec3 rayDirection,
                          vec3 sphereOrigin, float sphereRadius)
{
    float a = dot(rayDirection, rayDirection);
    vec3 s0_r0 = rayOrigin - sphereOrigin;
    float b = 2.0 * dot(rayDirection, s0_r0);
    float c = dot(s0_r0, s0_r0) - (sphereRadius * sphereRadius);
    float disc = b * b - 4.0 * a * c;
    if (disc < 0.0) {
        return vec2(-1.0, -1.0);
    }else{
        return vec2(-b - sqrt(disc), -b + sqrt(disc)) / (2.0 * a);
    }
}

float mie_phase(float g, float c, float cc)
{
    float gg = g * g;

    float a = ( 1.0 - gg ) * ( 1.0 + cc );

    float b = 1.0 + gg - 2.0 * g * c;
    b *= sqrt( b );
    b *= 2.0 + gg;

    return ( 3.0 / 8.0 / PI ) * a / b;
}

float rayleigh_phase(float cc)
{
    return ( 3.0 / 16.0 / PI ) * ( 1.0 + cc );
}

float density(vec3 p, float ph)
{
    return exp(-max(length(p) - innerRadius, 0.0) / ph);
}

float optic(vec3 p, vec3 q, float ph)
{
    vec3 step = (q - p) / fNumOutScatter;
    vec3 v = p + step * 0.5;

    float sum = 0.0;
    for(int i = 0; i < numOutScatter; i++) {
        sum += density(v, ph);
        v += step;
    }
    sum *= length(step);
    return sum;
}

vec3 in_scatter(vec3 o, vec3 dir, vec2 e, vec3 l)
{
    const float ph_ray = 0.05;
    const float ph_mie = 0.02;

    const vec3 k_ray = vec3( 3.8, 13.5, 33.1 );
    const vec3 k_mie = vec3( 21.0 );
    const float k_mie_ex = 1.1;

    vec3 sum_ray = vec3( 0.0 );
    vec3 sum_mie = vec3( 0.0 );

    float n_ray0 = 0.0;
    float n_mie0 = 0.0;

    float len = ( e.y - e.x ) / fNumInScatter;
    vec3 s = dir * len;
    vec3 v = o + dir * ( e.x + len * 0.5 );

    for (int i = 0; i < numInScatter; i++, v += s) {
        float d_ray = density( v, ph_ray ) * len;
        float d_mie = density( v, ph_mie ) * len;

        n_ray0 += d_ray;
        n_mie0 += d_mie;

        vec2 f = ray_sphere_intersect(v, l, vec3(0), outerRadius);
        vec3 u = v + l * f.y;

        float n_ray1 = optic(v, u, ph_ray);
        float n_mie1 = optic(v, u, ph_mie);

        vec3 att = exp(-(n_ray0 + n_ray1) * k_ray -
                       (n_mie0 + n_mie1) * k_mie * k_mie_ex);

        sum_ray += d_ray * att;
        sum_mie += d_mie * att;
    }

    float c  = dot( dir, -l );
    float cc = c * c;
    vec3 scatter =
        sum_ray * k_ray * rayleigh_phase( cc ) +
        sum_mie * k_mie * mie_phase( -0.78, c, cc );

    return 10.0 * scatter;
}

void main(void)
{
    vec3 lightDirection = normalize(lightPositionModel - positionModel);

    vec3 cameraDirection = -ray_direction(cameraPositionModel - positionModel);

    vec2 e = ray_sphere_intersect(cameraPositionModel,
                                  cameraDirection,
                                  vec3(0),
                                  outerRadius);

    vec2 f = ray_sphere_intersect(cameraPositionModel,
                                  cameraDirection,
                                  vec3(0),
                                  innerRadius);

    e.y = min(e.y, f.x);

    vec3 I = in_scatter(cameraPositionModel, cameraDirection, e, lightDirection);

    color = vec4(pow(I, vec3(1.0 / 2.2)), 1.0);
}

```

`cameraPosition`, `lightPosition`, and `planetPosition` are all provided in world coordinates. Two spheres are rendered. The first is a regular sphere with Phong shading. The second, slightly larger sphere using the above shader.

It results in an image like the following when the spheres are positioned at `0, 0, 0`.

But if the planet is positioned differently, you can see how the atmosphere no longer lines up correctly with the shading on the inner sphere. I.e., the above shader isn't taking into consideration the correct placement of the planet/light/camera in reference to planet/light/camera.

My understanding of the vertex shader was that I had moved the planetPosition, lightPosition, and cameraPosition into the models local space, and then in the fragment shader all the calculations were being done in reference to the models space. But either this doesn't work when factoring in the eye-ray, or I haven't correctly updated the positions from world-space to model-space.

# Answer
Ironically, I don't have enough reputation to comment, but I can post an answer. I agree with @PepeOjeda, your calculation of cameraDirection doesn't make sense. I think you should be calling `normalize` where you're calling `ray_direction`. Separately, you're passing vec3(0) as the sphere position into `ray_sphere_intersect`, and I think you actually want to pass the sphere position (`planetPositionModel` I'm assuming) instead. Those are the only problems I see.
> 2 votes

---
Tags: opengl, glsl
---


# Question
Title: javascript top down circle to circle smooth collision detection
I've been looking through a lot of answers here:

I couldn't find exactly the same thing I was looking for, which is proper top-down character sliding of circle to circle movement.

I tried implementing things from other answers here but whenever the character moves around circle, for some reason it just goes inside it (I was able to get it to spin around edges at one point but was unpredictable)

```
var aD = []
var r

function start() {
  r = new CanvasRenderer(can)
  my = new scene();
  eventHandler();

  my.add(new mesh({
    position: {
      x: 700,
      y: 200
    },
    radius: 70,
    color: "yellow",
    primitive: "circle",
    collision: "circle"
  }))

  my.add(new mesh({
    primitive: "circle",

    collision: "circle",
    color: "blue",
    name: "player",
    radius: 40,
    position: {
      x: 311,
      y: 75
    },
    origin: {
      x: 0.5,
      y: 0.5
    },
    onupdate(me) {

      aD.push(() => {
        r.ctx.beginPath()
        r.ctx.fillStyle = "red"
        r.ctx.arc(me.position.x, me.position.y, 5, 0, Math.PI * 2);
        r.ctx.fill()
        r.ctx.closePath();
      })

      if (!window.pl) pl = me
      var upKey = keys[38],
        downKey = keys[40],
        rightKey = keys[39],
        leftKey = keys[37],
        drx = 0,
        dx = 0,
        speed = 5,
        turningSpeed = 3
      //console.log(upKey)
      drx = leftKey ? -1 : rightKey ? 1 : 0
      forward = upKey ? 1 : downKey ? -1 : 0

      me.rotation.x += (
        (drx * Math.PI / 180 * turningSpeed)
      )
      me.rotation.y = 1;

      var xDir = Math.cos(me.rotation.x)
      var yDir = Math.sin(me.rotation.x)

      var xvl = xDir * forward * speed
      var yvl = yDir * forward * speed
      me.position.y //=col.y
      me.position.x // = col.x
      me.xvl = xvl
      me.yvl = yvl
      var next = {
        x: me.position.x + xvl,
        y: me.position.y + yvl
      }
      me.next = next
      var isColliding = []
      var coll;
      var curColls = []
      me.cols = []

      me.speed = speed
      me.yDir = yDir
      for (var i = 0; i < my.objects.length; i++) {
        let cur = my.objects[i];
        if (cur.name == me.name || cur == me) {
          break;
        }
        curColls = checkCollision(
          next.x,
          next.y,
          me.radius || me.scale.x / 2,
          cur
        )

        curColls.forEach(coll => {
          if (!coll) return;
          if (coll == me) {
            //  console.log("WH")
            return
          }

          cur.isCol = true
          isColliding.push({
            coll,
            object: cur
          })
          //    console.log(2222,coll.line)

        })
      }

      Array.from(me.cols)
        .forEach(q => {
          var w = isColliding.indexOf(q)
          if (w == -1 || q.object == me) {
            me.cols.splice(me.cols.indexOf(q), 1)
          }

        })
      var isme = me.cols.findIndex(q => q.object == me)
      if (isme > -1) {
        me.cols.splice(isme, 1)
        var ok = isColliding.findIndex(q => q.object == me)
        if (ok > -1) {
          isColliding.splice(ok, 1)
        }
      }
      if (!me.obs)
        me.obs = []
      var noad = false
      if (isColliding.length > 0) {

        isColliding.forEach(q => {
          var w = me.cols.indexOf(q)
          if (w == -1) {
            me.cols.push(q)
          }
        })

        var col = me.cols[0].coll
        var ob = me.cols[0].object
        if (!me.obs)
          me.obs = []

        if (col.type == "circle") {
          let vecBetweenX = next.x - ob.position.x;
          let vecBetweenY = next.y - ob.position.y;

          let heading = Math.atan2(vecBetweenY, vecBetweenX);

          var dst = Math.sqrt(
            vecBetweenX * vecBetweenX +
            vecBetweenY * vecBetweenY
          )
          var dirX = vecBetweenX / dst
          var dirY = vecBetweenY / dst

          var rt = heading

          var ris = ob.radius + me.radius

          var ax = Math.cos(rt) * ris
          var ay = Math.sin(rt) * ris

          /*
          var nx=ob.position.x+ax
          var ny=ob.position.y+ay
          */

          var nx = ob.position.x + dirX * ris
          var ny = ob.position.y + dirY + ris

          me.position.x = nx
          me.position.y = ny
          return

        }
      }

      me.position.x += xvl

      me.position.y += yvl
    }

  }));
  let i = setInterval(() => render(r, my), 16);
  r.on("resize", () => render(r, my));

}

function render(r, s) {

  s.update();
  r.render(s)
  aD.forEach(x => x());
  aD = []
}

onload = start;

function checkCollision(x1, y1, rad, ob) {
  var colls = [];
  if (ob.collision == "circle") {
    /*
        Ball 1:  center: p1=(x1,y1)  radius: r1
        Ball 2:  center: p2=(x2,y2)  radius: r2

        collision distance: R= r1 + r2
        actual distance:    r12= sqrt( (x2-x1)^2 + (y2-y1)^2 )

        collision vector: d12= (x2-x1,y2-y1) = (dx,dy)
        actual distance:  r12= sqrt( dx*dx + dy*dy )
    */

    var r1 = rad;
    var r2 = ob.radius;

    var p1 = [x1, y1]
    var p2 = [ob.position.x, ob.position.y]

    var R = r1 + r2;
    var R2 = R * R;

    var dx = p2[0] - p1[0]
    var dy = p2[1] - p1[1]

    var r12 = (
      dx * dx + dy * dy
    )

    var r12s = Math.sqrt(r12)

    var isCollision = r12s < R

    var colPoint = {
      x: (x1 * r2 + p2[0] * r1) /
        (r1 + r2),
      y: (y1 * r2 + p2[1] * r1) /
        (r1 + r2),
      type: "circle"
    };

    aD.push(() => {
      r.ctx.beginPath()
      r.ctx.fillStyle = "salmon"
      r.ctx.arc(colPoint.x, colPoint.y, 5, 0, Math.PI * 2);
      r.ctx.fill()
      r.ctx.closePath();
    })

    if (isCollision) {
      colls.push(colPoint)
    }
  }

  return colls;

}

function dot(x1, y1, x2, y2) {
  return (
    x1 * x2 + y1 * y2
  )
}

function eventHandler() {
  window.keys = {};
  addEventListener("keyup", e => {
    keys[e.keyCode] = false;

  });

  addEventListener("keydown", e => {
    keys[e.keyCode] = true;
  });
}

function CanvasRenderer(dom) {
  if (!dom) dom = document.createElement("canvas");

  var events = {},
    self = this;

  function rsz() {
    dom.width = dom.clientWidth;
    dom.height = dom.clientHeight;
    self.dispatchEvent("resize");
  }

  window.addEventListener("resize", rsz);

  let ctx = dom.getContext("2d");

  function render(scene) {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    for (let i = 0; i < scene.objects.length; i++) {
      let o = scene.objects[i],
        verts = o.realVerts;

      if (o.primitive == "circle") {
        var fnc = o.drawPrimitive[o.primitive]
        if (typeof(fnc) == "function")
          fnc(ctx)
      }
      ctx.fillStyle = o.color || "blue";
      ctx.lineWidth = 1;
      ctx.fill()
      ctx.stroke();
    }
  }

  Object.defineProperties(this, {
    domElement: {
      get: () => dom
    },
    ctx: {
      get: () => ctx
    },
    render: {
      get: () => render
    },
    on: {
      get: () => (nm, cb) => {
        if (!events[nm]) {
          events[nm] = [];
        }
        events[nm].push(data => {
          if (typeof cb == "function") {
            cb(data);
          }
        });
      }
    },
    dispatchEvent: {
      get: () => (name, data) => {
        if (events[name]) {
          events[name].forEach(x => {
            x(data);
          });
        }
      }
    }
  });

  rsz();

}

function scene() {
  let objects = [];
  Object.defineProperties(this, {
    add: {
      get: () => obj => {
        objects.push(obj);
      }
    },
    objects: {
      get: () => objects
    },
    update: {
      get: () => () => {
        objects.forEach(x => {
          if (typeof x.update == "function") {
            x.update();
          }
        });

      }
    }
  });
}

function mesh(data = {}) {
  let self = this,
    holder = {
      position: {},
      scale: {

      },
      rotation: {},
      origin: {}
    },
    position = {},
    scale = {},
    rotation = {},
    collision = "mesh",
    shape = null,
    origin = {},
    color,
    radius = 0,
    name,
    primitive,

    eventNames = "update",
    events = {},
    drawPrimitive = {
      circle(ctx) {
        ctx.beginPath();
        ctx.arc(
          self.position.x,
          self.position.y,
          radius,
          0,
          360 * Math.PI / 180
        );
        ctx.closePath();
      }
    },
    width = 1,
    height = 1;

  Object.defineProperties(position, {
    x: {
      get: () => holder.position.x || 0,
      set: v => holder.position.x = v
    },
    y: {
      get: () => holder.position.y || 0,
      set: v => holder.position.y = v
    },
    z: {
      get: () => holder.position.z || 0,
      set: v => holder.position.z = v
    }
  });

  Object.defineProperties(scale, {
    x: {
      get: () => holder.scale.x || 1,
      set: v => holder.scale.x = v
    },
    y: {
      get: () => holder.scale.y || 1,
      set: v => holder.scale.y = v
    },
    z: {
      get: () => holder.scale.z || 1,
      set: v => holder.scale.z = v
    }
  });

  Object.defineProperties(rotation, {
    x: {
      get: () => holder.rotation.x || 0,
      set: v => holder.rotation.x = v
    },
    y: {
      get: () => holder.rotation.y || 0,
      set: v => holder.rotation.y = v
    },
    z: {
      get: () => holder.rotation.z || 0,
      set: v => holder.rotation.z = v
    }
  });

  Object.defineProperties(this, {

    name: {
      get: () => name,
      set(v) {
        name = v
      }
    },
    primitive: {
      get: () => primitive,
      set(v) {
        primitive = v;

      }
    },

    drawPrimitive: {
      get: () => drawPrimitive
    },
    width: {
      get: () => width,
      set(v) {
        width = v
      }
    },
    height: {
      get: () => height,
      set(v) {
        height = v
      }
    },
    position: {
      get: () => position,
      set: v => {
        position.x = v.x || 0;
        position.y = v.y || 0;
        position.z = v.z || 0;
      }
    },

    radius: {
      get: () => radius || (width * scale.x) / 2,
      set: v => {
        radius = v;
        this.width = radius / 2
        this.height = radius / 2
      }
    },
    scale: {
      get: () => scale,
      set: v => {
        scale.x = v.x || v.x === 0 ? v.x : 1;
        scale.y = v.y || v.y === 0 ? v.y : 1;
        scale.z = v.z || v.z === 0 ? v.z : 1;

      }
    },
    rotation: {
      get: () => rotation,
      set: v => {
        rotation.x = v.x || 0;
        rotation.y = v.y || 0;
        rotation.z = v.z || 0;
      }
    },
    color: {
      get: () => color,
      set: v => {
        color = v;
      }
    },
    update: {
      get: () => () => {
        if (events["update"]) {
          events.update.forEach(x => {

            x(this);
          });
        }
      }
    },
    on: {
      get: () => (nm, fnc) => {
        if (!events[nm]) events[nm] = [];
        events[nm].push(stuff => {
          if (typeof fnc == "function") {
            fnc(stuff);
          }
        });
      }
    }
  });

  eventNames.split(" ").forEach(x => {
    var name = "on" + x;
    if (!this.hasOwnProperty(name)) {
      Object.defineProperty(this, name, {
        get: () => events[name],
        set(v) {
          events[x] = [
            data => {
              typeof v == "function" && v(data)
            }
          ];
        }
      });
    }
  });

  for (let k in data) {
    this[k] = data[k]
  }

}
```

```
canvas {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0px
}

.wow {
  float: right;
  z-index: 1298737198
}
```

```
<br> game test 2d minimal<br>
<meta charset="utf-8">
<button onclick="start()" class=wow>ok</button>
<canvas id=can></canvas>
```

Just arrow keys to move

Relevant part for circle sliding (contains code from different examples that was used at different times but nothing works):

```
if(col.type=="circle"){
    let vecBetweenX = next.x - ob.position.x;
    let vecBetweenY = next.y - ob.position.y;

    let heading = Math.atan2(vecBetweenY, vecBetweenX);

    var dst = Math.sqrt(
        vecBetweenX*vecBetweenX
        +
        vecBetweenY*vecBetweenY
    )
    var dirX=vecBetweenX/dst
    var dirY=vecBetweenY/dst

    var rt= heading

    var ris = ob.radius + me.radius

    var ax = Math.cos(rt)*ris
    var ay = Math.sin(rt)*ris

    /*
    var nx=ob.position.x+ax
    var ny=ob.position.y+ay
    */

    var nx=ob.position.x+dirX*ris
    var ny=ob.position.y+dirY+ris

    me.position.x = nx
    me.position.y = ny
    return
}

```

I tried using method suggested in answer, but player is still getting stuck at circle, while the ideal intended behavior is for the player to slide along the edges

# Answer
Your collision resolution is using player movement speed and angle, which are irrelevant if you're just trying to find a point to place them that's outside of the collision. You want to push the player in the direction of the angle from the collider to the player, so use `heading` for `rt`, and instead of multiplying the sine and cosine by `speed*forward`, multiply it by the sum of the circles' radii, because that's the distance you want between their centers. Then just add that to `ob.position` to get the final point. Remove the `rr` bit.

So, something like this:

```
let vecBetweenX = me.position.x - ob.position.x;
let vecBetweenY = me.position.y - ob.position.y;

let heading = Math.atan2(vecBetweenY, vecBetweenX);

var rt = heading

var radiiSum = ob.radius + me.radius

var ax = Math.cos(rt) * radiiSum
var ay = Math.sin(rt) * radiiSum

var nx = ob.position.x + ax
var ny = ob.position.y + ay

me.position.x = nx
me.position.y = ny
return

```

A simpler way of doing the same thing is just subtracting the collider's position from the player's position to get a direction vector, normalize it and multiply it by the sum of the radii, and then as before add it to the collider's position.

```
let vecBetweenX = me.position.x - ob.position.x;
let vecBetweenY = me.position.y - ob.position.y;
let dist = Math.sqrt( vecBetweenX*vecBetweenX + vecBetweenY*vecBetweenY )

// normalize
let dirX = vecBetweenX / dist
let dirY = vecBetweenY / dist

var radiiSum = ob.radius + me.radius

var nx = ob.position.x + dirX * radiiSum
var ny = ob.position.y + dirY * radiiSum

me.position.x = nx
me.position.y = ny
return

```
> 1 votes

---
Tags: collision-detection, mathematics, collision-resolution
---


# Question
Title: Level Instance Blueprint Option Hidden UE5
So, here’s the deal. I’m trying to make level instance blueprints with Megascan assets (i.e. group them and convert to a single blueprint), but when I select them all and right-click, I can’t find the option to convert the meshes to a level instance blueprint. Why is this happening, and how can I fix it? (I’m using a Mac, just so you know.)

# Answer
In Unreal Engine 5, you should be able to achieve a better result with the merge operation. Navigate to Tools, then select "Merge Actors" to open up the Merge Actors window and perform the action.
> 1 votes

---
Tags: unreal, unreal-5
---


# Question
Title: Possible to render true HDR from Unity URP on supporting display?
Can the Unity URP actually output an HDR signal to a supporting monitor?

I don't mean HDR values with tone mapping applied to map the values to an SDR signal, but actual HDR values displayed on the monitor.

Currently it is clamping the values and I can visually see they are dimmer when compared to an HDR image on the same screen.

If it is possible, is it also possible to render HDR on a supporting iphone?

Thanks

# Answer
When tempted to ask "does \[engine\] support \[feature\]", it pays to do a quick search first.

Let's type "unity hdr output" into a search engine. The very first result is Unity - Manual: High Dynamic Range, which says:

> # Render pipeline compatibility
>
> For information about support for HDR Rendering and HDR Output in the Scriptable Render Pipelines URP and HDRP, see the Render pipeline feature comparison.

And clicking that link takes us to a table showing:

> # Color
>
> **HDR**
>
> | Feature | Built-in Render Pipeline | URP | HDRP |
> | --- | --- | --- | --- |
> | HDR rendering | Yes | Yes | Yes |
> | HDR output | No | No | Yes |

So there's your answer: no it is not possible to send HDR colour output from the Universal Render Pipeline. Found in one search and two clicks. Try doing this search yourself next time to find your answers faster.
> 1 votes

---
Tags: unity, hdr, unity-urp
---


# Question
Title: How to keep a camera confined inside a 3d Collider
I am trying to create a confiner for my camera using the bounds of a collider, the issue is that when I hit the wall of the confiner, I need to disable the camera movement, but since I disable it, I now cannot move it at all.

I've tried all I can think of like storing the last "valid" position and restoring it if confiner is hit, but that does not seem to work.

```
void HandleInput()
    {
        if (inputDisabled)
            return;

        //Speed controls
        if (Input.GetKey(KeyCode.LeftShift))
        {
            movementSpeed = fastSpeed;
        }
        else
        {
            movementSpeed = normalSpeed;
        }

        // Adjust movement speed based on camera zoom
        movementSpeed *= (cameraTransform.localPosition.y / zoomSpeedFactor);

        Vector3 adjustedForward = transform.forward;
        adjustedForward.y = 0;

        //Movement controls
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
        {
            newPosition += (adjustedForward * movementSpeed);
        }
        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            newPosition += (adjustedForward * -movementSpeed);
        }
        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            newPosition += (transform.right * movementSpeed);
        }
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            newPosition += (transform.right * -movementSpeed);
        }

        //Zoom controls
        if (Input.mouseScrollDelta.y != 0 && !EventSystem.current.IsPointerOverGameObject())
        {
            newZoom -= Input.mouseScrollDelta.y * zoomAmount;
            newZoom.y = ClampValue(newZoom.y, zoomClamp.x, zoomClamp.y);
        }

        if (!collider.bounds.Contains(newPos)) //DISABLE MOVEMENT
            return;

        transform.position = Vector3.Lerp(transform.position, newPosition, Time.unscaledDeltaTime * acceleration);
        cameraTransform.localPosition = Vector3.Lerp(cameraTransform.localPosition, newZoom, Time.unscaledDeltaTime * acceleration);
    }

```

# Answer
I realized all I have to do is use `Mathf.Clamp` using the `Collider.Bounds` `Min` and `Max`.
> 0 votes

# Answer
I think your use case is exactly what Cinemachine was built for. Access it from the package manager and read up on it in the docs.

Cinemachine is a camera add on package that helps with follows, confinement, cinematic camera pans, etc etc.
> -1 votes

---
Tags: unity
---


# Question
Title: How to convert a list into coordinates in pygame
I'd like to have a map in my pygame game but don't want to waste time moving each individual object in it. To resolve this, I'd like to iterate over a list like this:
\[1, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 1, 0, 0, 0\]
where 1 means there is a rock and 0 means there is nothing. How would I convert this list into coordinates of where to place each block?

UPDATE:
To clarify if I have a list of lists like so:
\[
\[1, 1, 1, 1, 0\],
\[0, 0, 0, 0, 0\],
\[0, 0, 0, 0, 0\]
\] And dimensions 500x500,
I'd like the program to put a wall of rocks from x=0 to x=400, with each rock being 100x100.

What I mean is: I'd like to find x-y coordinates to place the rock based on where the 1 is on the map list of lists.

# Answer
Sorry for the delay in getting back to this question. Based upon your clarification I have completely re-written this answer.

What you're basically doing here is "tiling". You have a 5x5 map (real pixel dimensions are 500x500) and each coordinate on the map can have a rock or not have a rock. You will have a tile for no rock on the map, and another tile which will have the rock. This tile will be a static or animated graphics image like a .png, .jpg, or .gif and you would copy -- or "blit" -- it onto the display in the proper place.

I don't have those graphical files so I have to make do. I will create a "surface" for the tile, and instead of importing an image into it I'll just fill it with a background colour:

```
tileEmpty = pygame.Surface((100,100))
tileEmpty.fill((0,255,0))

```

I will base the tile for the rock on the empty tile, then just add the "rock" over top of whatever's there. The "rock" isn't elaborate in any way, just a grey circle, but I first will copy the empty tile:

```
tileRock = tileEmpty.copy()
tempRect = tileRock.get_rect()
pygame.draw.circle(tileRock, (128,1,28,128), tempRect.center, tempRect.center[0], tempRect.center[0])

```

What's going on here is that I'm creating a new surface for the rock by copying the surface which contains the "empty" map tile. To do the figuring-outs I'll need to get the `rect` of that surface. On that surface I will simply draw a grey circle. The `.draw.circle()` method is well-documented, but I'll need the colour, the centre of the `rect`, and the width of the line used to draw the circle. The `.center` property of the `rect` conveniently gives us the width of the line as well as the centre of the circle.

You wouldn't do it this way, of course; you'd have a tilesheet already drawn up with 100x100 (or whatever) images and you'd just pick off of that.

As per my previous reply, you'd still use `y * mapwidth + x` to pluck the map contents from the bitmapped map contents. What's different in this reply is that you'd multiply the `x` and `y` by the width of the tile to find where to put it.

There are many ways that you could get tiles onto the display, but for simplicity I've chosen to use a simple 'for x / for y' iteration. In practice you'd have a limited view onto your map and you'd have to calculate a rectangle out of a much larger bitmap to display it.

Here is a working program which demonstrates the basics:

```
import pygame

pygame.init()

#this is the entire 5x5 map as a bitmap
bitMap = [1,1,1,1,0,
          0,0,0,0,0,
          0,0,0,0,0,
          0,0,0,0,0,
          0,0,0,0,0]

#some predefined colour constants
FIELD = pygame.Color(0,255,0)    #colour of the empty field
ROCK = pygame.Color(128,128,128) #colour of the rock

#set up the main 500x500 display
display = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Tile Time")

#make an empty tile
tileEmpty = pygame.Surface((100,100))
tileEmpty.fill(FIELD)

#make a tile with a rock
tileRock = tileEmpty.copy()
tempRect = tileRock.get_rect()
pygame.draw.circle(tileRock, ROCK, tempRect.center, tempRect.center[0], tempRect.center[0])

#draw the map -- very straight-forward!
for x in range(5):      #because bitMap is 5x5
    for y in range(5):  #because bitMap is 5x5
        dest = (x * 100, y * 100)   #calculate where to put the tile
        if bitMap[y*5+x] == 1:      #gets contents of bitmap at (x,y)
            display.blit(tileRock, dest)    #display a rock
        else:
            display.blit(tileEmpty, dest)   #display not a rock

pygame.display.flip()   #update the display

input()

```

The `input()` is just to keep the code simple; no need for a game loop for this. Depending how you run the code you may need to Ctl-C out of it, though.
> 1 votes

---
Tags: tiles, matrix, pygame
---


# Question
Title: How do I make soft tile-based collision?
I've done some simple tile based collision: Move character, look up the tiles moved into, and if solid, push them back out. I move on each axis independently, because this gets them to eject properly. My game uses 2D Sprites, but its physics is 3D, so this includes the X, Y, and Z axes.

I don't want every tile to feel like a brick of lead. I want walking into a bush to feel springy. I want to feel a bit of sag when walking on snow. I want running up a steep slope to feel harder than running down a decline. I want for some tiles to bounce you off like trampolines, and for others, to absorb the full impact so that you stop in your tracks.

All of this works very much against the "hard thing pushes out" design I have so far. It occurs to me to that with slopes, it might not to work to push against each axis individually. Now that I think about it, how do I handle collisions with more than one tile at once if they have different softness properties?

How does one accomplish this sort of thing using tiles-based (or in my case, more accurately, blocked-based) collision?

# Answer
> 3 votes
You mentioned a list of goals you want to achieve. In my opinion, they cannot be achieved using a single out-of-the-box way. You can unify them by wrapping the existing physics engine, But each effect needs to be implemented separately.

> I don't want every tile to feel like a brick of lead.

Unfortunately, most modern general-purpose physics engines use Rigid\_body to describe physical objects. This is an ideal model for convenient calculations. In the real world, the force generated by the collision between objects comes from their deformation, while the rigid body collision ignores the deformation process and directly performs a Elastic\_collision(or a Inelastic collision). So by default they just feel like bricks.

> I want walking into a bush to feel springy. I want to feel a bit of sag when walking on snow.

You can implement your own spring components using Hooke's law. It applies opposite forces to the connected two objects every frame. The magnitude of this force depends on the compression of the spring. When the elasticity coefficient is high, you get a bush, and when the elasticity coefficient is small, you get a snow field.

> I want running up a steep slope to feel harder than running down a decline.

Add a horizontal force when running, and the component perpendicular to the incline is automatically canceled when going uphill. Or detect the angle of the incline and change the running speed according to it, solve this problem at the business layer.

> I want for some tiles to bounce you off like trampolines, and for others, to absorb the full impact so that you stop in your tracks.

You can artificially specify the energy loss factor(or Coefficient of restitution) for inelastic collisions. It specifies how much energy will be converted from kinetic energy to other energy in a collision. (In the physics engine they just disappear). Some engines include it in physical materials. You can implement it yourself, or find out if the physics engine you are using has this feature.

---
Tags: collision-resolution
---


# Question
Title: Do I have to clear the entire target with a single color every frame?
Do I have to clear the entire target with a single color every frame? I thought the newly drawn ones will overwrite the old ones.

# Answer
From the documentation (emphasis mine):

> **Calling clear** before drawing anything **is mandatory**, otherwise the contents from previous frames will be present behind anything you draw. **The only exception is when you cover the entire window with what you draw**, so that no pixel is not drawn to. In this case you can avoid calling clear (although it won't have a noticeable impact on performance).

So you're right, if you plan to redraw the *whole screen*, *every frame*, then you don't *have* to call `clear`.

...but since calling `clear` is cheap, it is highly recommended to do so: it will prevent some eventual *WTF?!!!?* during future development (e.g. *WTF*, why are there weird shapes when I debug my character movement code *?!!!?*). Also, since it is generally expected to be there, you'll get less weird looks at you when you have other devs look at your code. Without going into details, it can help you find some bugs with your code that would be harder to track if you didn't do it.
> 2 votes

---
Tags: sfml
---


title: How can I make a multi-line dialog box?

text:
# Question
Title: How can I make a multi-line dialog box?
I'm trying to make a dialog box with pygame, and initially everything was going well. I printed the letters sequentially on the screen and it works very well in a single line of text, but when I use `\n` to add an extra line it does not go to the new line.

When I searched, I found that `pygame.font.Font` and `pygame.font.SysFont` could not print `\n`. So what do you think, how should I go about printing multi-line messages?

# Answer
> 2 votes
I saw this question two weeks ago, but I didn't really have the time to properly answer it so I left it for someone more experienced to answer. I'm a little surprised that this question has not yet been answered (nor flagged as I'm sure it's a duplicate).

So, the answer is that `.Font.render()` and `.SysFont.render()` do not process newlines, as is stated in the documentation. The solution is to keep track of the height of everything you have been printing so that you can begin displaying text on the next line. It's actually a lot easier than it sounds:

```
import pygame

SIZE = 80
OFFSET = 0

pygame.init()

WHITE = pygame.Color(255,255,255)
BLACK = (0,0,0)

display = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Font Test")
display.fill(WHITE)
pygame.display.flip()

fobj = pygame.font.SysFont(pygame.font.get_default_font(), SIZE)

nextLine = 0

#display first line
t = "Line 1"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,0))
nextLine += fobj.size(t)[1] + OFFSET

#display second line
t = "Line 2"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,nextLine))
nextLine += fobj.size(t)[1] + OFFSET

#display third line
t = "Line 3"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,nextLine))
nextLine += fobj.size(t)[1] + OFFSET

pygame.display.flip()

input()

```

This is a fully working stand-alone example. The `input()` is to avoid adding an event-processing loop, but depending how you run the code you may have to Ctl-C out of it.

The program uses the variable `nexLine` to determine where to display the next line of text, and which gets updated every time you display a line. I don't know what your level of experience is so I've written the code to be easy to read and understand, yet easy to put into a `def` (`nextLine` would need to be made global) or as a method inside some kind of dialogue class object (`nextLine` would be referenced as `self.nextLine`).

I've also included a nifty little constant named `OFFSET`. It's set to zero, but the purpose of that is to demonstrate that you can adjust the calculated height of each line you render. You can adjust `OFFSET` so that the lines are closer together or further apart. I've put it in the program as a constant, but the caveat with using an offset like this is that it varies quite a bit with the size and face of the font. I could be mistaken, but if I remember correctly it is not a linear progression based on font size, and it's different again if you use a different font face.

---
Tags: python, pygame
---


# Question
Title: How to generate mipmaps with min value sampling for Hierarchical Z test (HiZ)?
I'm on the way to add HiZ to my SSR protocol as explained here

I would like to use `generatemip`, but can't find how to select sampled pixels based on a min value comparison. Is this possible with `generatemip`?

Must this be done by shader only? If so, I may need to select the previous mip level as resource and the next one as render target. Is this feasible? What is the regular method for this purpose?

As stated in my comment I'm creating the initial texture with generatemip flag and from it create its rendertarget and shaderesource. I copy the regular depthbuffer to level 0 and use generatemip to have the HiZ. But I don't know how to have a min value instead of sampled neighboring pixels.

Alternatively I can use a shader but just can't understand how you retrieve a rendertarget for a given mip level. It seems it has something to do with copysubresource or updateresource but I don't understand how to use it.

# Answer
After some workaround this is my solution

Using DX11 generatemips

Create texture pTex with mip flag on (eventually fixed number of miplevel) and D3D11\_BIND\_RENDER\_TARGET | D3D11\_BIND\_SHADER\_RESOURCE flags

Create pRTV rendertarget for this pTex with RTVDesc.Texture2D.MipSlice = 0;

Create pSRV shaderesourceview for this pTex with SRVDesc.Texture2D.MipLevels = MipCount; SRVDesc.Texture2D.MostDetailedMip = 0;

Using it

If the initial image has the same format as the pRTV rendertarget use CopyResource

Else you can do this (example copy an initial D24 to a R16)

Set the initial image as resourceview (D24). Set render target pRTV (R16); Set a pixel shader to copy the initial image to the pRTV; Draw square;

If both cases finish with DX11 generatemips(pSRV);

If not using generatemips (owner defined downsampling)

Create texture pTex as previously Create an array\[MipCount\] of ppRTV rendertarget and ppSRV shaderesourceview for this pTex with

```
For n=0 to <MipCount
   RTVDesc.Texture2D.MipSlice = n;
   create ppRTV[n]
   SRVDesc.Texture2D.MipLevels = 1;
   SRVDesc.Texture2D.MostDetailedMip = n;
   Create ppSRV[n]

```

Doing mipmap

As previously you start by copying the initial image but to the ppRTV\[0\] Then

```
 for (n = 1; n < MipCount; n++)
     SetShaderResources(0, 1, & ppSRV[n - 1]);
     Update shader constant data with current viewportsize if required
     Then divide current viewport size /2
     SetViewports(1, current new size);
     SetRenderTargets(1, ppRTV[n], NULL);
     Render a quad
     Free targets at that point to avoid in debug mode DX messages of resource still bound as target

```

The default of the array ppSRV is that you will use MipCount texture slots in the shader if you need to use all the mips. To avoid this I combine the two methods by creating the main pRTV and main pSRV as for generatemip AND ppRTV\[MipCount\] and ppSRV\[MipCount\] And after manual mipmap generation with ppRTV and ppSRV I copy each ppRTV\[n\] to each miplevel in main pSRV.

```
    ID3D11Resource* pDst;
    gSRHiZ.pSRV->GetResource(&pDst);
    D3D11_BOX Box;
    Box.back = 1;
    Box.front = 0;
    Box.left = 0;
    Box.top = 0;
    Box.right = gViewPort.Width;
    Box.bottom = gViewPort.Height;
    for (DWORD n = 0; n < 8; n++)
    {
        ID3D11Resource* pSrc;
        gSRHiZ.ppRTV[n]->GetResource(&pSrc);
        gpDC11->CopySubresourceRegion(pDst, n, 0, 0, 0, pSrc, n, &Box);
        Box.right /= 2;
        Box.bottom /= 2;
        pSrc->Release();
    }
    pDst->Release();

```

I don’t like having a copy of the same resources twice but I did not find any way to do it better to have only one texture slot used.

Using it in the final shader

With generatemip or after the copy of array to the main pSRV you declare and use a texture as usual

```
 Texture2D txMip : register(t8);
 ....
 txMip.load(xy, MipLevel)

```

If using an array of SRV you declare an array of texture

```
 Texture2D txMip[8]: register(t8);
 .....
 txMip[n].load(xy, 0)

```

Below the result with owner PShader downsampling using array of RTV and SRV with final copy to the main SRV.

For HiZ I need a min value check like this:

```
int3 TexS = int3(Input.Tex.xy, 0);// xy sized to previous screen size in VShader
float FinalColor0 =  txDiffuse.Load(TexS).r;
float FinalColor1 =  txDiffuse.Load(TexS+int3(1,0,0)).r;
if ((FinalColor1==0)||(FinalColor1==1))FinalColor1=FinalColor0;
float FinalColor2 =  txDiffuse.Load(TexS+int3(1,1,0)).r;
if ((FinalColor2==0)||(FinalColor2==1))FinalColor2=FinalColor0;
float FinalColor3 =  txDiffuse.Load(TexS+int3(0,1,0)).r;
if ((FinalColor3==0)||(FinalColor3==1))FinalColor3=FinalColor0;
return min(FinalColor0, min(FinalColor1, min(FinalColor2, FinalColor3)));

```

The lower sized mips suffer this known border problem (white border in last views). If someone can point me to a better method for border checking it will be great

After some refinements I found that a single texture can be used to generate a single RTV/SRV with miplevels AND/or the same texture can be used to generate arrays of RTVs and SRVs. Updating one or the others updates in fact everything (e.g. updating SRV\[5\] or writing to RTV\[5\] updates miplevel 5 of SRV. Indeed the CopySubRegion loop is not necessary.
> 1 votes

---
Tags: directx11, mipmaps, sampler-state
---


# Question
Title: Make Spherical Hole on objects in Unreal Engine 5
I want to make something like this rasengan effect on a tree for my game (just for learning).

Full Video Domonstration Link here (length: 1 min)

I am new to unreal engine. So, according to my research so for I can use Procedural Meshes in UE5 and then slice it anywhere but ig that only works with a plan. Also rasengan (that magic/power ball whatever you say lol) works more like an eraser it doesn't just cuts it off rather it vanishes the whole area it collides with.

So, is it possible to create that thing with unreal engine 5?

# Answer
We can use Subtract Boolean operation on mesh to get this result. It requires a plugin "Geometry Script" (which is experimental atm). Found a good yt video that helped a lot.
> 1 votes

---
Tags: unreal, unreal-5
---


title: Non-stretching health bar?

text:
# Question
Title: Non-stretching health bar?
Here's what I want:

Here's what I got:

What is this procedural image unmasking called? Popcap didn't do image-splitting (source images below), but I feel like I'm missing the obvious here.

(Source images)

I'm currently using a world-space canvas, an empty game object with a slider component, and two UI image components.

I'm giving Unity a fresh shot after some bad experiences with it previously, so I apologize for my newbie-ishness.

# Answer
> 13 votes
Since *Canvas \> LoadBar \> Grass* has an `Image` Component, all you need to do is set the **Image Type** property to "Filled". Then, the Inspector will expose new properties: **Fill Method** and **Fill Origin**. Set the former to "Horizontal" and the latter to "Left". Use the **Fill Amount** property to change the fill percentage of your *Grass* `Image`. Change this value programmatically, passing the loading percentage in the \\$\[0, 1\]\\$ interval.

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


# Question
Title: i got a problem with my script , it is said that startcoroutine does not exist in my context
here is my script :

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

public class powerup : MonoBehaviour {

    public float multiplier = 2f;
    public float duration = 4f;

    public GameObject PickupEffect;

    void OnTriggerEnter (BoxCollider other)
    {
        if(other.CompareTag("Car"))
        {
            startcoroutine   (  Pickup(other));
        }
    }

    IEnumerator Pickup(BoxCollider Car)
    {
        Instantiate(PickupEffect, transform.position, transform.rotation);
        Car.transform.localScale *= multiplier;
        yield return new WaitForSeconds(duration);

        Car.transform.localScale /= multiplier;

        Destroy(gameObject);
    }
}

```

# Answer
> 2 votes
It's `StartCoroutine`, not `startcoroutine`. C# is a case-sensitive language. Capitalization matters.

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


# Question
Title: How to "merge" multiple intersecting circles so that only the outer edges of each show?
In my RTS (In Unity) each unit or building has strategic circles in a similar fashion to SupCom. If you have multiple units or buildings selected it looks like the picture to the left. I want to make it look like the picture to the right, where anything inside the outer edges of their circles is no longer shown.

I draw these using vectrosity, mentioning this just in case vectrosity provides a way of doing this, or can be modified to do this.

The circles are essentially just an array of points with lines drawn in between them. How would I go about "merging" the circles inside of their overlapping area?

This is similar to: How to make unit selection circles merge?, however I am not interested in a shader solution.

Edit: To re-explain the above.:

I'm not seeing how the answers are applicable. I've read through the other thread before posting, which is why I posted it here to avoid this exact thing (being marked as a duplicate). I have an array of points with straight lines in-between them to create a circle-like effect. This is not a true circle, but a really granular polygon. I am interested in solutions that are achievable in C# within Unity, not with shaders or with rendering mechanics.

Edit2: Another picture based on one of Roberts suggestions

This seems viable, though computationally expensive. If I have a circle made up of 250 points, and 50 circles all intertwined that's 615,500 checks in a worst-case scenario.

# Answer
Draw each circle on some memory, then after all are drawn, set the inside of every circle to zeros, clearing any intersection lines.

clarification On some memory is meant to indicate separate texture Set to 0 is meant to indicate set to transparent.

setting inside transparent on second draw sequence is fill with transparent color with fillcircle of radius ( radius - linewidth) on second drawing
> 2 votes

# Answer
I know this thread is ancient, but I want to share information to anyone looking.

In Unity it's simple! You can merge the circles, using two objects. "A" circle sprite and "B" sprite mask. If you set A's to "Visible Outside Mask" then B will mask all instances of A. Creating nice merging.

( Ignore that I duplicated the prefab inside itself, it's just to demonstrate )
> 2 votes

# Answer
You probably could draw, and save 'intersection points' any point where two circles draw a point at same location. Then use that set, knowing that inside and outside changes when an intersection occurs. You would then only need to check any one point between two intersections to know the status of an entire arc between any two intersections.

Fewer checks with that.

in your drawing, you would only have to check one point inside, and one point outside,(for each circle) to know the status of the arcs. Each circle has two arcs, so two checks for each circle.

Circles with only one intersection point would have to be handled, but that would not be difficult. If odd number of intersections, you would know in one case two circles only share one point in common and could adjust algo for that. And that case should be rare.
> 1 votes

# Answer
If you don't care about the interior being painted in, there's a really simple solution. First, draw all circles in black. Next, draw all the circles again in white, with a smaller radius - basically subtract a border width from the radius. The result will be a constant thickness black border around a white area. You could maybe even use this black / white info in a stencil buffer to do more advanced rendering.
> 1 votes

# Answer
If any point is closer to the center of any circle then the radius of that circle clip it.

Although you would probably want to find the intersection points where any two distances equal to the radius of a circle, from any two different circle centers are equal, to get clean edges where intersection occurs.

basically any point inside another circle is clipped, and you can determine if in the circle by distance to radius, or any other method. Probably could, when first finding a point inside a circle, move it to the edge value, so that the edges of the many circles would be connected also.
> 0 votes

# Answer
Or draw your circles as filled, then trace the edge that would work also.

tracing edges method would only be computationally a better method with a very large number of circles. Where edge trace is faster then second set of drawing.
> -1 votes

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


# Question
Title: How to make unit selection circles merge?
I would like to know how to make this effect of merged circle selection. Here are images to illustrate:

Basically I'm looking for this effect:

How the merge effect of the circles can be achieved ? I didn't found any explanation concerning this effect. I know that to project those texture I can develop a decal system but I don't know how to create the merging effect.

If possible, I'm looking for purely shaders solution.

# Answer
There are a few tricks you can do:

**Z-buffer**

After you have rendered all other objects, for each unit render a transparent circle of smaller size with max Z value. Then render selection circles decals on the ground. Since they are below in Z-order, they will be discarded when under units.

Being fully transparent means that the circle gets written **only** to Z-buffer (max Z value). Now when you render decals, they are tested against Z buffer values, and if they are passing the test they get rendered (which happens only outside of the circles)

**Stencil**

Same as with previous approach, but this time use a stencil buffer. Render smaller circles for units with some stencil value, then render selection decals. Setup stencil to discard any elements with your stencil value.
> 8 votes

# Answer
I know this thread is ancient, but I want to share information to anyone looking.

In Unity it's simple! You can merge the circles, using two objects. "A" circle sprite and "B" sprite mask. If you set A's to "Visible Outside Mask" then B will mask all instances of A. Creating nice merging.

( Ignore that I duplicated the prefab inside itself, it's just to demonstrate )
> 1 votes

# Answer
You could for example check in the decal rendering pixel shader if there is an intersection with any other decals and kill the pixel if so. It's quite efficient to do for this kind of circular decals.
> 0 votes

# Answer
Off the top of my head, if these decals are drawn as discs, I would test each circle for intersection against each other circle, and put the intersection points into an array. Then draw arcs that are not inside an intersection. This is not a shader solution, though.
> 0 votes

# Answer
Do you mean those blue circles on the ground?

There may be a smarter way to do this but consider my solution as an example how this can be done. Render your circles to a separate empty texture of the size of the screen. At this point you can blend them together, however you want. Depending on your needs you can write the full color or just the information that a circle is present at given pixel. However, you will definetely need a depth information for each pixel that you write if you want a Z-test effect.

When you render the terrain after the previous step, you can sample the previously created texture, using screen coordinates in pixel shader, as UVs. Now you know, that the circle should or shouldn't be projected at given pixel of the terrain. However, this way it will work as if the Z-test was disabled, so a terrain can't hide any circle. If you want a terrain to hide circles that are behind it, perform a depth test before blending a circle with terrain texture. You can use a small bias to enable rendering of circles that are just a little bit under the terrain but you would still like them to render.

---

Edit: Now in order to get the effect of merged circles what you need to do is: When rendering to the separate texture, you need to check if there is already a circle rendered where you are trying to render a new one. (Check if the texture has a value there) if so, erase this pixel. This should give the effect of "outline" when two or more circles overlap. For this to work correctly, however you will need to do this test only for the inside of the circle, not the border. So when rendering circles, write some specific value to the output texture, which indicates that it is a circle inside. Then you just need not to render anything on the circle inside and you should be good.

Edit2: For your simple red/green example: Before you render any pixel, check if this pixel is not already green. If it is, don't render. This will do the trick. In fact, while writing to the texture you can even use red/green for outside/inside of the circle, and then while rendering the terrain read those values and convert them to a desired color.

If my answer is too abstract by any chance, let me know.
> 0 votes

# Answer
There are a few options. As a general method, stencil buffers often come in very handy where certain drawing needs to be masked out, like the outline where the circles overlap in your example.

In this case, I think this can be done just as easily without a stencil buffer. You can use the depth buffer to eliminate the outline where the circles overlap. The idea is that you draw the interior of the circles into just the depth buffer (since we don't want to see the interior), and then draw the outline. This way, the part of the outline that overlaps with another circle will be eliminated by the depth test.

The only caveat is that you have to be careful about depth fighting. You can use a small offset to make sure that the outlines are in fact behind the interior, and get eliminated by the depth test. An alternative would be to use `glPolygonOffset()`.

Let's say you have two circles that are parallel to the xy-plane, with centers at (x1, y1, z) and (x2, y2, z). And you have these draw functions:

```
// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

```

The sequence of drawing then looks like this, with `delta` being a small offset:

```
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);

```
> 0 votes

# Answer
You want stenciling here. Your first pass renders the circles to the stencil buffer. The second pass renders the visible *outline*, anywhere the stencil buffer *has not changed.* The second pass must use geometry which is larger than the first pass, in this case, a simple linear scalar is sufficient.

While the solution I have for drawing outlines over here is more than you need (as that shader turns every mesh edge into a full quad), it does follow this approach: drawing the original model to the stencil buffer, then rendering a larger version where the stencil buffer is still 0.
> 0 votes

---
Tags: shaders, selection
---


# Question
Title: Offset input sent to blend tree based on Character's Local Rotation
I am developing a top down twin stick shooter. I am running into a issue where if I change my character's rotation, the Unity Blend Tree animation does not play the correct animation that corresponds to that relative rotation. For example if my Character is facing north and I walk forward, the animation plays fine, but if I rotate my character 180 degrees (facing south), when I walk forward it will play the backwards animation.

https://media.giphy.com/media/cmx1aOm0UOjCed8MJT/giphy.gif

I believe this is because I am just sending the inputs from the analog stick, and not offsetting the values based on the rotation of the character. I am using 2 floats (horizontal and vertical) to control the blend tree. How can I offset the float values from the input based on the character's local rotation? Current code below,

```
 void Update()
{
    if (!ReInput.isReady) return; // Exit if Rewired isn't ready. This would only happen during a script recompile in the editor.
    if (player == null) return;
    GetInput();
    Move();
    Look();

}

private void GetInput()
{
    // Get the input from the Rewired Player. All controllers that the Player owns will contribute, so it doesn't matter
    // whether the input is coming from a joystick, the keyboard, mouse, or a custom controller.

    mhorizontal = player.GetAxis("Move Horizontal"); // get input by name or action id
    mvertical = player.GetAxis("Move Vertical");

    lHorizontal = player.GetAxis("Look Horizontal");
    lVertical = player.GetAxis("Look Vertical");
    //fire = player.GetButtonDown("Fire");
}

void Move()
{

    if (mhorizontal != 0 && mvertical != 0)
    {
        Vector3 rightMovement = right * moveSpeed * Time.deltaTime * mhorizontal;
        Vector3 upMovement = forward * moveSpeed * Time.deltaTime * mvertical;
        //Vector3 heading = Vector3.Normalize(rightMovement + upMovement);

        // transform.forward = heading;
        transform.position += rightMovement;
        transform.position += upMovement; animator.SetFloat("Vertical", mvertical, 0.1f, Time.deltaTime);
        animator.SetFloat("Horizontal", mhorizontal, 0.1f, Time.deltaTime);
    }

}

void Look()
{
    if (lVertical != 0 && lHorizontal != 0)
    {
        float cameraFacing = Camera.main.transform.eulerAngles.y;
        Vector3 inputVector = new Vector3(lHorizontal, 0, lVertical);
        Vector3 turnedInputVector = Quaternion.Euler(0, cameraFacing, 0) * inputVector;
        transform.LookAt(turnedInputVector + transform.position);

    }

}

```

# Answer
Ok, I found a pretty simple solution. I just needed to rotate/offset the X,Y input with the X/Y values from the player's and Camera's Y rotation. Below is my solution:

```
    void Move()
{

    if (mhorizontal != 0 && mvertical != 0)
    {
        Vector3 rightMovement = right * moveSpeed * Time.deltaTime * mhorizontal;
        Vector3 upMovement = forward * moveSpeed * Time.deltaTime * mvertical;
        //Vector3 heading = Vector3.Normalize(rightMovement + upMovement);

        // transform.forward = heading;
        transform.position += rightMovement;
        transform.position += upMovement;

    }

    Direction.x = mhorizontal;
    Direction.y = mvertical;
    Direction = Rotate(Direction, transform.rotation.eulerAngles.y);
    //Direction =Quaternion.AngleAxis(-45, Vector3.up) * Direction;
    print("Direction is: " + Direction);
  //  Direction = Quaternion.Euler(0, transform.rotation.eulerAngles.y , 0) * Direction;

    animator.SetFloat("Vertical", Direction.y, animationDamp, Time.deltaTime);
    animator.SetFloat("Horizontal", Direction.x, animationDamp, Time.deltaTime);
}

public Vector2 Rotate(Vector2 v, float degrees)
{
    return Quaternion.Euler(0, 0, (degrees + -Camera.main.transform.rotation.eulerAngles.y)) * v;

}

```
> 1 votes

# Answer
```
var x = Input.GetAxisRaw("Horizontal");
var z = Input.GetAxisRaw("Vertical");
moveDir = new Vector3(x, 0, z).normalized;
Vector3 animationVector = transform.InverseTransformVector(moveDir);
anim.SetFloat("moveX", animationVector.x);
anim.SetFloat("moveZ", animationVector.z);

```
> 0 votes

---
Tags: unity, animation, input
---