# Question
Title: How to check for collisions between objects with the same script?
I am creating a game where there would be two objects instantiated. Each one has a script (to check for collisions), a `Rigidbody2D` component and a `Collider2D` of course.

The thing is that I want to call a function whenever the two objects collide each other, but when those two objects collide, the function is called **twice** (once from object1, and once from object2) but I want it to be called **once**.

# Answer
> 1 votes
The way I handle this is to check the instance ID, and let the object with the lower ID "own" the collision.

```
void OnCollisionEnter2D(Collision2D collision) {

    if (collision.gameObject.TryGetComponent(out ThisScript otherscript)) {
        // Two of the same script colliding.

        if (gameObject.GetInstanceId() > collision.gameObject.GetInstanceId())
            return; // I have the higher ID — abort!

        // Put code to call only once in
        // same-script collisions here.
    }
}

```

---
Tags: unity, c#, collision-detection, physics
---


title: OVR Lip Sync in Unity WebGL project

text:
# Question
Title: OVR Lip Sync in Unity WebGL project
I am using the Oculus VR (OVR) Lip Sync Plugin for an avatar in a Unity project which I want to deploy to a browser using WebGL.

The issue is that WebGL doesn't support Unity's `Microphone` API. I know that some aspects of OVR Lip Sync use `Microphone` for real-time Lip Sync of voice through a mic, but I just need it to generate Lip Sync from prerecorded audio files. This doesn't actually need a microphone but it seems to want to use the `Microphone` API.

I tried commenting out the *OVRLipSyncMicInput.cs* class where it invokes the `Microphone` API. The project works fine with lip sync in the Unity editor. The WebGL project builds and runs but the lip sync is not working.

The actual error I get when trying to build the project before commenting out the *OVRLipSyncMicInput.cs* class is: *Assets\Oculus\LipSync\Scripts\OVRLipSyncMicInput.cs: error CS0103: The name 'Microphone' does not exist in the current context*

Does anyone know if it is possible to get the OVR Lip Sync plugin to work with WebGL or if there is another way to deploy a Unity project to a browser?

# Answer
> 0 votes
To the best of my knowledge, there isn't a way to get the Oculus VR Lip Sync plugin to work in a WebGL Unity project, and there isn't another way to deploy a Unity project to a browser without WebGL, so the only solution is to find another Lip Sync plugin that works in WebGL such as AmplitudeSALSA.

# Answer
> -1 votes
A coworker was able to get that working using using Microphone Pro and some custom code.

---
Tags: unity, webgl, unity-webgl, browser, avatar
---


# Question
Title: How to make a character fall through a BoxCollider2D?
Currently trying to make a 2D game in Unity and I'm trying to make the part where if the character falls in a hole it goes back to spawn, but I currently have a ground box collider blocking it, which covers the entire floor. Can anyone help?

# Answer
> 1 votes
After looking around for the best solution, it seems that using the Layers in Unity is pretty awful when you want to code something with them. Best solution is to have an object with a trigger collider over your hole, and attach a script that listens to trigger collision to check if the player has collided with it; so when he does collide the script tells the physics engine to ignore all collision between that ground collider and the players collider.

The code looks something like this:

```
public class GroundHole : MonoBehaviour
{
    [SerializeField] private GameObject _ground;

    private void OnTriggerEnter(Collider col)
    {
        if (col.transform.CompareTag("Player"))
            Physics.IgnoreCollision(_ground.GetComponent<Collider>(), col, true);
    }

    private void OnTriggerExit(Collider col)
    {
        if (col.transform.CompareTag("Player"))
            Physics.IgnoreCollision(_ground.GetComponent<Collider>(), col, false);
    }
}

```

# Answer
> 0 votes
You can add triger for example if player inside trigger you can remove player collider (or make player do not collide with the box collider layer) and it will falls. Or use 2 colliders as DMGregory said.

---
Tags: unity, 2d, physics, collision-resolution
---


# Question
Title: Seam visible on sphere or torus made in Blender when using a texture atlas
I'm making a game in OpenGL with C++.

I have a problem with my vertices or texture coordinates - there's a seam visible on the sphere where the texture wraps around:

If I use "nearest" filtering, the result is better, but it does not completely fix the issue:

```
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

```

The line is thinner with this, but not fixed. In debug mode, I can see the issue with the blue line that seems to be the start of the texture before:

I can bypass the issue using a isophere, but this doesn't fix anything. I want to use all blender shapes. (I have the same issue with the torus shape)

In Blender, there is no visible issue:

I use textures of size 256\*256, with a texture atlas:

I convert the texture coordinates with this code:

```
for (int x = textureStart ; x < textureSize; x++) {
    if (counterForWidth % 2 == 0) {
        shape.texturesCoordonateNoSorts.at(x) = (shape.texturesCoordonateNoSorts.at(x) + currentTextureId) / (GLfloat)bigTexture.pointsTextures.size();
    }
    counterForWidth++;
}

```

I modify the texture coordinate (Axis X), using the `currentId` of the texture, and divide by the total amount of textures.

How can I fix this?

# Answer
> 1 votes
Texture atlases aren't ideal for 3D models - you tend to get artefacts like the one you've seen if you need to wrap or clamp the texture coordinates. Supporting that requires some careful shader modification to handle them correctly.

What's probably happening along your seam is that you have two vertices with very different UVs right next to each other. This will cause the GPU to pick the smallest possible mipmap for a few pixels along that seam (because of the huge UV gradient), and the smallest mip map won't be a sensible colour.

Also note that you can run into similar problems with bilinear texture filtering too, because that can cause texture samples to read into adjacent atlas textures for UVs that are close to the edge.

Possible solutions:

* Avoid using a texture atlas for cases where the texture needs to wrap or clamp. Note that most 3D modelling programs assume that textures wrap.
* As you're using a 1D texture atlas, you could make the seam align with the top and bottom of the texture, and not the left and right, and enable wrapping / clamping in that direction. This won't help if you need to wrap / clamp in both directions though.
* To alleviate some of the issues with mip maps, you can reduce the number of mips for the texture to 8, so the smallest mip has a height of 1, and a width of 13 in this case. Mips smaller than that won't contain useful data. This won't completely fix the problem on it's own though.
* You could even remove all of the mip maps, but that will cause aliasing and hurt performance.
* You can modify the pixel shader to do wrapping / clamping on the UVs. To get it to look correct at the seams, you'll need to make use of the `ddx` and `ddy` functions along with SampleGrad.

See https://download.nvidia.com/developer/NVTextureSuite/Atlas\_Tools/Texture\_Atlas\_Whitepaper.pdf for more detailed discussion on making texture atlases work nicely.

# Answer
> 0 votes
I had solve this issue using the method of Adam, avoid using a texture atlas.

Of course this need few changes to work, but i think it's better to do this for lots of things, like the issue encounter here and for me when i was using texture atlas, the max size of a texture limits me (texture with sfml), growing very quickly if i want to use 4k texture.

So now i use one texture per shape, all shapes are in a object.

Thanks you for all your answers.

---
Tags: opengl, c++, blender, texture-atlas, sphere
---


# Question
Title: Camera not following the player after spawn
After my character spawns, the camera just stays in the same place. How can I solve that?

Here's my code:

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

public class SideScrolling : MonoBehaviour
{
    private Transform mario;

    private void Start ()
    {
        mario = GameObject.FindWithTag("Player").transform;
    }

    private void LateUpdate()
    {
        Vector3 cameraPosition = transform.position;
        cameraPosition.x = Mathf.Max(cameraPosition.x, mario.position.x);
        transform.position = cameraPosition;
    }
}

```

# Answer
Change

```
cameraPosition.x = Mathf.Max(cameraPosition.x, mario.position.x);

```

To

```
cameraPosition.x = mario.position.x;

```

Look at the following code

```
Vector3 cameraPosition = transform.position;
cameraPosition.x = Mathf.Max(cameraPosition.x, mario.position.x);
transform.position = cameraPosition;

```

If `cameraPosition.x` \>= `mario.position.x`, then the camera won't move if mario is moving toward negative X direction, because `Mathf.Max(cameraPosition.x, mario.position.x)` would return the value of `cameraPosition.x`.
> 0 votes

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


# Question
Title: Is texture switching a good idea (OpenGL, 2D)?
Let's say I have two atlases for character animation. One atlas represent idle and walk. The other one represents striking.

I usually combine atlases into one file, however I thought about using multiple textures. It is technically possible to bind another texture based on some state, but what are downsides of this approach?

It seems to me, like rendering and animation defining logic will get more complicated. I will have to implement not only UV/uniforms switching, but also rebinding of a texture, some kind of relation between GL\_TEXTURE**N** and the texture object itself.

Is this practice usually considered? What are upsides and downsides compared to atlasing?

# Answer
Generally speaking, atlasing isn't that easy to implement either. You have to associate each animation frame with texture coordinates. If your sprites are not adjusted to viewport pixels, you can have problems with texture coordinates rounding, causing neighbouring frames "bleed" into current frame.

Texture atlases are usually considered faster than switching textures. You are also not guranteed to have a lot of slots for binding textures (How many textures can I usually bind at once?).

Third option is to use bindless textures (https://www.khronos.org/opengl/wiki/Bindless\_Texture). The OpenGL wiki article I linked goes into them in great detail, but TL;DR is that you can bind a texture, get a handle for it and then pass it to your shader as a uniform sampler2D variable. Changing a uniform variable for every texture might be as expensive as binding a new texture; however, you can bind more textures (if you create an array of samplers), or even bind 2DTextureArrays (unfortunately it requires every texture to have the same resolution, but it allows indexing textures with a layout qualifier variable, i.e. use multiple textures atlases in a single object).
> 1 votes

---
Tags: opengl, texture-atlas, multitexturing
---


# Question
Title: Realistic Camera/Screen Shake from Explosion
I'd like to shake the camera around a bit during an explosion, and I've tried a few different functions for rocking it around, and nothing seems to really give that 'wow, what a bang!' type feeling that I'm looking for. I've tried some arbitrary relatively high frequency sine wave patterns with a bit of linear attenuation, as well as a square wave-type pattern. I've tried moving just one axis, two, and all three (although the dolly effect was barely noticeable in that case).

Does anyone know of a good camera shaking pattern?

# Answer
I've got decent camera shake by applying Perlin noise to the camera's orientation. It gives you a decent big jolt with higher frequency shaking built in, and can look really good.

http://mrl.nyu.edu/~perlin/doc/oscar.html has more details and sample code for generating noise.
> 36 votes

# Answer
If you are referring to that juddering screen shake from an explosion, I have tried to implement this in my prototype game (it's 2d but should translate to 3d quite well, I expect). Take a look at the youtube video and see if that's what you're looking for - the screen shake kicks off about 1:35

Anyway, the way I achieved it was to create a viewport for the sceen and store the centre point (`centre`).

When an explosion kicks off, I create a random `radius` of ~30px. I then offset the viewport from `centre` by this many pixels in a random direction.

For each subsequent update (between draws to screen), I reduce `radius` by 10-20% and offset the viewport by this many pixels from `centre` again. However, instead of picking a random angle for this offset, I instead take the previous viewport angle from `centre` and added 180+/-60 degrees to it.

So basically, each update (or 10-20ms or so), I offset the viewport by a diminishing number of pixels from the `centre` of the screen.

Here's some pseudocode:

```
viewportCentre = (400,300) //Lets say screen size is 800 x 600
radius = 30.0
randomAngle = rand()%360
offset = ( sin(randomAngle) * radius , cos(randomAngle) * radius) //create offset 2d vector
viewport.setCentre(viewportCentre + offset) // set centre of viewport
draw()

while(true)  //update about every 10-20ms
{
    radius *=0.9 //diminish radius each frame
    randomAngle +=(180 +\- rand()%60) //pick new angle
    offset = (sin(randomAngle) * radius , cos(randomAngle) * radius) //create offset 2d vector
    viewport.setCentre(viewportCentre + offset) //set centre of viewport
    draw() //redraw
}

```

I usually stop the screen shake when radius gets lower than 2.0, at which point I reset the viewport back to `centre`.
> 18 votes

# Answer
To make a camera shake "feel" correct is less about the direction of motion and more about acceleration curves.

Camera shakes are diving into the realm of animation and so all the rules of action/reaction apply. If you are moving in a linear fashion from point to point it will feel smooth and uniform and not like an impact.

If you shake your head back and forth you'll notice that it moves fastest at the midpoint between changing direction and slows down on each side as you first have to decelerate and then start up in the new direction.

Here is a listing of various easing functions to apply to your motion. You might want to only EaseOut the first motion to make it feel a little more abrupt, and then EaseInOut the rest to simulate the head/camera movement.
> 4 votes

# Answer
wkerslake is right, camera shakes appear to be more complex than you might think.

When emulating a shaking camera you'd have to think about what type of camera (operator) you want to mimic. The weight of the camera affects inertia, eg. heavier cameras smooth out small 'random' movements. A camera operator on a rail or in a car adds additional noise.

Using Perlin or Simplex noise is definitely an option, then it's all about finding the right balance between different noise ratios. But I found using interpolation between values is less computationally intensive and can be just as effective.

A while ago, I've found a Maya script that seems to get a lot of things right. You could take a look at that.

Also, you might want to take a look at Gran Turismo (5), their team did an impressive job at doing various types of realtime camera shaking when you watch a replay in the game.
> 3 votes

# Answer
If you've got dynamic object physics \[probably not the right word, but sort of what I mean\], where any objects not fixed would be 'blown away' by the explosion, you could have the camera affected as an object like that.
Only difference would be just change the rotation/pitch/yaw/roll of the camera, and not the position.
Other than that, maybe generate a random number sequence and convert those to rotation somehow? Think that heightmap, grayscale stuff may be an example; they're not totally different, but are random.
> 2 votes

# Answer
I recently added a camera shake effect to Open Saucer after stumbling across (serendpitous autocomplete) a method that sets a camera's *projection offset*. This attribute is animated bidirectionally using dossinant sine waves of around 10 Hz, with a cubed falloff. Contrary to rotating/panning the camera, this leaves the perspective intact, which makes it more like a 2D shift, and with it - I think - easier on the eyes. One might argue it is also "more realistic", since perspective remains unchanged when panning a camera in real life as well.

The exact implementation would be engine-specific. In the Dry engine I use it's a matter of calling `SetProjectionOffset(Vector2)` on the `Camera`, either directly or through an attribute animation. This then affects the camera's 4x4 projection matrix, by scaling the first two elements of its third column.
> 1 votes

---
Tags: camera
---


# Question
Title: Can't move rigidbody2d when using animations
I have a player moving and jumping by changing its x or y velocity. It worked well until i created a walking and idle animation. Now, the player is animated correctly when idle or walking, but does not move on the x axis. It can still jump (still using physics), but not move horizontally.

The "Apply root motion" is checked on the animator component, so I don't understand why the character can't move horizontally.

When I disable the animator component, everything works just fine, so why won't my player move on the X axis ?

# Answer
> 1 votes
Maybe bcause u controll global X position of player in the animation: "Position.x"; You need to controll only local positions of your object inside animations in this case you will be able to use keys to change global X position of player.

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


# Question
Title: Can I see my unpublished game store page in the steam client?
I am working on setting my steam store. I am having trouble visualizing how store and library graphics are used. It would help me if I could see the graphics as used in the steam client.

I can see the graphics using the store in beta mode in a browser:

but in the steam client, no graphics are visible:

\[edit\] removed store link since its not helpful

Is it possible to configure the client to show my game graphics before the store goes live?

# Answer
Based on my own experiences, unpublished games will not appear in the steam client apps--the page can be viewed in the browser if you are log in using the account that owns (will publish) the game.
> 0 votes

---
Tags: steam, appstore
---


# Question
Title: Rhythm game, Sync music start with the start of the level in fixedUpdate
I'm working on a rhythm based android game similar to Guitar Hero.

I have a kinematic rigidbody moving downwards with tapobjects (colliders) inside which need to be pressed when moved above the button.

The big problem: No matter what I try, I can't get the first movement of the rigidbody to be aligned with the exact start of the music. There is always a delay of around +-100ms and more.

Intialization:

```
void Start()
{
    velocity = beatTempo / 60f;
    startDelayedBy = 0f;
    setupAudioInputLag = false;
    firstFixedUpdate = false;
    songLag = 0.0692f;   // time in seconds when first beat occurs of the audio
    songLagStep = ( beatTempo / 60f ) * songLag; // calculate the distance of songlag on y axis
    velocityAdd = new UnityEngine.Vector3(0f, -velocity, 0f);
}

```

What I tried, Example 1:

```
private void FixedUpdate()
{
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayDelayed(1f);
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
    if (startDelayedBy >= 1f)
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
    if (setupAudioInputLag)
    {
        startDelayedBy += Time.fixedDeltaTime;
    }
}

```

Example 2:

```
private void Update()
{
    getAccurateDspStart = AudioSettings.dspTime;
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayScheduled(AudioSettings.dspTime + 1.0f);
        dspTimeStore = AudioSettings.dspTime + 1.0f;
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
}

private void FixedUpdate()
{
    if (getAccurateDspStart >= (dspTimeStore) && setupAudioInputLag)
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

```

Example 3:

```
private void Update()
{
    getAccurateDspStart = Time.time;
    getAccurateDspStartOld = AudioSettings.dspTime;
}

private void FixedUpdate()
{
    accurateDspTime = getAccurateDspStartOld + (Time.time - getAccurateDspStart);
    if (accurateDspTime != 0f)
    {
        if (setupAudioInputLag == false)
        {
            beatMusic.PlayScheduled(accurateDspTime + 1.0f);
            dspTimeStore = accurateDspTime + 1.0f;
            rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
            setupAudioInputLag = true;
        }
    }
    if (accurateDspTime >= (dspTimeStore) && setupAudioInputLag)
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

```

Example4:

```
private void FixedUpdate()
{
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayDelayed(1f);
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
    if (beatMusic.time != 0)
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

```

And much more I tried over several days without even getting close. I need accuracy about 10-20ms.

Using `PlaySheduled(dspTime)` in start and starting movement instantly in `FixedUpdate` was the closest, but least reliable for some smartphones.

# Answer
> 0 votes
The simplest thing you can do with 0 ms delay in the result is: Create a manager that will start the music, and then run the required Start methods for all objects. For example:

```
[SerializeField]
List<ObjectsStarts> starts;
public void Run()
{
    audio.Play();

    for(int i = 0; i < starts.Count(); i++)
    {
        starts.CustomStart();
    }
}

```

---
Tags: unity, c#, audio, music
---


# Question
Title: How to create mobs for mmofps and synchronize their animation, movement, actions with all players?
Help me grasp the concepts of mobs and in game events that the world should control in terms of multiplayer games.

I want to create some test game in browser for players to run and shoot mobs. I want to use Cocos Creator for this.

I have some knowledge about client-server synchronization from Godot documentation - there it's pretty simple. You basically run another Godot instance on server side, headless, without graphics but with basic stuff like physics, animation etc. So in terms of making mobs that move truly in the game world Godot approach seems easy to grasp.

But in Cocos Creator and similar web game engines... They require separate server with socket.io connection.

Yes, it solves the problem of player positions and somewhat bullets positions. Because one client shoots bullet and sends updates to every other client via server.

But what about mobs? Monsters, enemies. I mean in Godot situation it's pretty simple. Server there is basically client and server at the same time. Mob moves in Godot server by engine rules, colliding, attacking and sending updates to everyone.

But with Cocos Creator I don't understand how server can calculate mob, it's position, it's navmesh behaviour, it's animation state etc.

Do everyone really recreate whole engine functionality on server to make monsters abide engine and world rules?

And if one of the clients creates mob - what happens when client disconnects? I assume mob simply disappears?

# Answer
There shouldn't be anything stopping the server from handling calculating mob positions, behavior, etc., unless I'm misunderstanding something about socket.io. When it comes to recreating the engine functionality over on the server side though, what you could instead do is separate that code out, and reuse the same code on your server as in your clients.

This has a couple of bonus upsides as well. For example, since a server would typically only send snapshots of the world to players 10-64 or so times per second, in an MMO usually on the lower side of that if not lower, having the same logic on the client would mean you could use that for both

1. Interpolating - i.e., "filling in the gaps" between the server updates, so things look smoother, and
2. Extrapolating - i.e., trying to "guess the future" and e.g. keep moving players etc. in the direction they are already moving, guessing that they'll keep doing that, to avoid the situation that used to be common in older games, where you had to shoot behind or in front of enemies.

As for creating a mob, typically that would only be done on the server, as it's its task to keep track of mobs and their positions, and so on, so when a client disconnects, that should not affect anything, as that data is still present on the server, and still sent out to all other players. If you do want a client to be able to create a mob and have that synchronized with everyone else, usually you would probably instead send a command to the server saying "Hey, create this mob for me", and if the server allows that client to do so, it would create it server-side, and start updating all clients about it.

As DMGregory mentioned though, when it comes to animations, typically the server wouldn't be calculating those, but the client would instead based on the information sent from the server calculate that locally on the client.
> 1 votes

---
Tags: multiplayer, online, cocos3d
---


# Question
Title: Unity shader to give thickness to flat plane
I have this hexagonal grate floor:

Which is a flat plane with the following shader:

The hex lattice created using the method by Andrew Hung. Albedo and metallic/smoothness shader are just simple textures.

I would like the hex grate to have a little depth without adding lots of polygons (and then using vertex position shifting).

Perhaps a little like an outline shader but offset below the grate? Is it even possible?

Many thanks.

# Answer
If I'm following your node graph right here, you should be able to take a copy of your alpha map, offset it a bit based on the view angle, and then subtract the original alpha map from your offset one, and use the resulting image as a mask for whatever you want your extrusion/depth to look like. Then mix that in with the rest of the grid, using the sum of the alphas added together for your alpha channel (to make sure both the original grid and the extruded bit are visible).

The illusion will probably break at extreme angles, but with some tweaking it should be possible to get something at least passable until further inspection.

One way of doing this, would be to

1. Get the dot product of the camera forward direction and the surface normal. This will give you a number between -1 to 1, where 1 means they are entirely aligned, -1 they point in exactly opposite directions, and anything else means something in-between.
2. Use this value as a scaling factor for how much offset your "extrusion layer" needs; when looking from above, you'd want this to be zero, and the more parallel to the plane, closer to one, so something like `1 - abs(dot(cameraForward, normal))` could work.
3. To then find the actual values to offset by, you could take the cross product of the camera forward direction and the surface normal, to give you a new vector perpendicular to both, which lies on the plane of the surface.
4. Use the components of that cross product to offset; exactly how will depend on your coordinate system, and order of the operand of the cross product, in my case it ended up working with `(-y, x)`.
5. Then multiply that offset by the scaling factor from step 2, and potentially some other factor to make the effect more or less subtle if needed, and the result should then be our offset vector.
6. Take your original alpha map use to render your grid transparency, create a new copy of it offset by the offset vector, then subtract the original alpha map from it. The resulting map should then be white only where the extrusion is supposed to be visible.
7. Calculate color/roughness etc. for your extrusion however you want, for example, as a tweaked copy of the original version.
8. Use the map from step 6 to mix your original grid, and the extrusion, keeping the original wherever the map is black, and the extrusion where it is white.
9. Use your original alpha map and your extrusion alpha map added together as the final alpha map, which should then be white (opaque) everywhere the original grid was, as well as wherever the extrusion now is.

I took a quick stab at doing this in Blender, with a node graph like so:

resulting in an effect roughly like this:

where black is then the "extrusion".

You will likely have to tweak the exact scales etc. to get this to look right for you, but an approach roughly like that should get you something similar to a 3D effect on your plane.
> 2 votes

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


# Question
Title: How to make the player pass through only certain objects, but not others?
Experimenting with my 1st Unity project. It's about a top down swimmer. By toggling the swimmer's collider, he can swim under boats:

```
if (Input.GetKeyDown(KeyCode.A)) swimmerCircleCollider.enabled = !swimmerCircleCollider.enabled;

```

At the same time I don't want him to be able to swim under the wharf, which is like an uncrossable barrier/border/wall or simply the end of playable area. How can I achieve that?

Is the idea of disabling the collider wrong in the first place? If so, please provide some guidelines for a better solution.

# Answer
> 4 votes
* You can go to **Edit**-\>**Project Setting**-\>**Physics** or **Physics 2D**-\>**Layer Collision Matrix**. To change what you want your player pass through or not.
* To change it via code like what you wanted, I have a solution here. Ex: your Player's Layer position is 6 & your Enemy is 7.

```
private bool isSwimmingUnderWater = false;
void Update()
{
    if (Input.GetKeyDown(KeyCode.A))
    {
        isSwimmingUnderWater = !isSwimmingUnderWater;
        Physics2D.IgnoreLayerCollision(6, 7, isSwimmingUnderWater); //it will set the val of the Layer Collision of the Player and Enemy whether true or false
    }
}

```

I have tested it with my game and it works.

# Answer
> 1 votes
To achieve a barrier you also could add a child object which gets activated and has an appropriate box collider.

But the Physics2D solution by **Tien Hung** is way more elegant!

---
Tags: unity, c#, physics, collider
---


# Question
Title: Why am I getting a "NullReferenceException: Object reference not set to an instance of an object" Error when calling List.Contains()?
I'm trying to make a randomized generation engine for a top down dungeon crawler, in the Binding of Isaac style, however, the code is throwing out a multitude of errors when I try it compare a value to a value in the list. The errors are on lines 44, 155, 271, and 384 which are all `if` statements that are all formatted as such:

```
if(gameMaster.PositionsOfRooms.Contains(generatorPoint.transform.position))

```

Code Snippet:

```
public class DoorGenerator : MonoBehaviour

public bool isdoor;
public bool facingUp;
public bool facingDown;
public bool facingRight;
public bool facingLeft;
public bool generated;
public bool startingRoom = false;
public int runningRoomCount;
public GameObject generatorPoint;
public GameMasterScript gameMaster;
public Transform teleportfromCords;
public Transform teleporttoCords;
public GameObject camera;
// Start is called before the first frame update
void Start()
{
    gameMaster = GameObject.Find("GameMaster").GetComponent<GameMasterScript>();
    teleportfromCords = transform.Find("TeleportPoint");
    camera = GameObject.Find("Main Camera");
}

// Update is called once per frame
void Update()
{
    if(generated == false && gameMaster.targetRooms > gameMaster.roomsGenerated)
    {
        GenerateRoom();

    }
}

public void GenerateRoom()
{if(generated ==false){
generated = true;
{
    if(facingUp == true)
        {
        generatorPoint = transform.parent.Find("CreateRoomUp").gameObject;
        if(gameMaster.PositionsOfRooms.Contains(new Vector3(generatorPoint.transform.position.x, generatorPoint.transform.position.y, generatorPoint.transform.position.z)))
        {
            return;
        }
        else
        {

```

# Answer
A `NullReferenceException` means you tried to "reach into" an object (ie. with a `.dot` or an `[index]`) while that object reference is set to `null`, meaning that there's no object there to reach into. It's like if I asked you what color your car is, and you don't own a car: there's no valid answer to that question because the premise is wrong.

If you're saying `gameMaster.PositionsOfRooms.Contains(new Vector3(generatorPoint.transform.position.x, generatorPoint.transform.position.y, generatorPoint.transform.position.z))`, then one of `gameMaster`, `gameMaster.PostionsOfRooms`, or `generatorPoint` is null here. You need to figure out which one it is and correct the code, either by fixing it so that it won't be null here, or by checking for null first and not calling this if the objects you're relying on aren't available.
> 2 votes

# Answer
In your if statement you are searching for a newly created position instance - very likely the newly created instance will never be in the list.

As of my understanding you want to check if the newly generated position value is inside the list of possible position values right?

If so you could do something like this:

```
    // this is your gameMaster-List
    List<Transform> positions = new();

    // this is your newly created position
    Vector3 positionToCheck = new(0, 0, 0);

    // this is the newly created position but in string format
    string positionToCheckString = positionToCheck.ToString();

    // start to loop through your avaible position
    foreach (Transform avaiblePosition in positions)
    {
        // optional null check
        if (avaiblePosition == null) continue;

        // check if string of an position instance is equal to your newly created position
        if (avaiblePosition.ToString() == positionToCheckString)
        {
            // the value is inside the list
        }
        else
        {
            // the value is not in the list
        }
    }

```
> 0 votes

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


# Question
Title: No "USB Dialog Connection" option when enabling Developer Mode
I am trying to enable Developer Mode on my Meta Quest 3 and am running into a problem while following 2 different official developer docs:

I can confirm that I have logged in `dashboard.meta.com` using my normal Facebook account, I've created an "Org" and verified my credit card. I've enabled developer mode from inside the **Headset Settings** on the *Meta Quest* app on my phone.

Both documents now want me to do the exact same thing: put on my headset, and then go to **Settings \>\> System \>\> Developer**. And from there, they want me to turn on the **USB Dialog Connection** option.

The problem is, when I go to **Settings \>\> System \>\> Developer**, I only see these options:

As you can see, no mention of a "**USB Dialog Connection**" option. There is only a "**USB Link Auto-Connect**" option, but that's already enabled. Can anyone spot where I'm going awry? Am I in the wrong screen perhaps?

Also, secondary to that, can anyone clue me in here and explain what this "Quest PC app" is (from my screenshort) with respect to Meta Quest 3 development, and what it might be used for? Is it a debugger/emulator perhaps? I Googled it and it looks like it was something used for Oculus, so I'm not sure why the Meta Quest 3 has options available for it.

# Answer
The quest pc app is used to manage your quest on your pc. It contains a store for VR games that (I believe) are meant to run on your computer. Furthermore, it acts as a bridge between your quest and the pc, and it needs to be running to make your quest talk via USB or airlink. I don't think I have needed usb communication since airlink. I am using a quest 1, so it may be different, but with airlink connected, your unity VR project (and any other game or app that can connect to the quest), should connect automatically. Try setting up airlink and see if it connects. If it does, you should be good to go for development.
> 0 votes

---
Tags: virtual-reality, oculus
---


# Question
Title: How to get the SteamID of the currently active user from the filesystem or shell? (Windows)
Can anyone tell if it's possible to programmatically read the SteamID of the currently logged on user on Windows? Either from the filesystem or through cmd / powershell?

Context: I'm looking to make a mod for a Steam game and it's going to exchange some data with a 3rd party server. But I'll need a way to reliably tell the users SteamID for authentication and resource assignment purposes. With the scripting engine of the game I can read files from the filesystem, make http requests or run other binaries like cmd, but that's about it. The Steam SDK/API functions are not exposed.

Currently I'm reading the "LastOwner" property of the appmanifest vcf file that is created with every game in the steamapps folder. However, that one is just the ID of the user that installed the game, which is not necessarily the ID of the active user.

# Answer
Feeling a little dumb answering my own question, but while I tried to implement Tims answer I came across an easier solution. I found that Steam stores some data about the current Steam process in the Windows Registry. And yes, it contains the SteamID of the logged on user.

Path: **HKEY\_CURRENT\_USER\Software\Valve\Steam\ActiveProcess**

This key has an "ActiveUser" dword, which is the SteamID3 of the currently logged in user (in hex).

Knowing that, we can use the windows cmd shell to query or export the key and store it in a temporary file to read it out and extract the SteamID pretty easily.

```
reg export HKCU\Software\Valve\Steam\ActiveProcess steamsession.reg

```

This works only if you have access to the windows shell or can run batch files. If you fully rely on the filesystem only, Tims answer is probably the only way to go.
> 4 votes

# Answer
There is SteamID data in the Steam Program Files folder.

There may be a better way to do this, but what I've found is that the folder Steam\userdata has a series of sub-folders, and each folder is named with the steamID3 number of a user. So for each user who has logged into that Steam installation, there is a folder named with their steamID3 number.

For example, my steamID3 is \[U:1:17\], and I have a folder named Steam\userdata\17.

If you then look in that steamID3 named folder you will see another folder named config (path being Steam\userdata\\config). It is modified when Steam is started, and Date modified updated to the time when Steam was launched.

So I think you could do this...

1. Check Steam\userdata folder contents
2. If there is just one folder there, you have the steamID3 of the player (it's the directory name)
3. If there is more than one user folder present, look at all the config files in each steamID3 named folder, and find the one with the newest config folder

Run this scan at the start of your game. You now have the ID of the last person to start up Steam. Which you can probably assume is the currently logged in user.

One thing I do not know is what happens if you start Steam, then log out one user and log in another. You should try this, and confirm that the config file for the newly logged in user gets updated.
> 2 votes

# Answer
If your app is being launched as an intermediate launcher for a game (by specifying `your_app.exe %command%` in the launch parameter options) then you can get the username from the `SteamAppUser` environmental variable.

That wasn't quite what I needed as I needed to locate the remote folder for my app so I needed to get the account\_id from the username. I was able to find that in the steam config.vdf. My requirements also needed to work cross platform (win, mac, Linux).

Here's the python code I used to put it together:

```
    _user=os.environ['SteamAppUser']
    _game=os.environ['SteamAppId']
    steam_game_path=pathlib.Path(os.getcwd())
    _steam_path=steam_game_path.joinpath('..','..','..')
    _steam_config=_steam_path.joinpath('config','config.vdf')
    with open(_steam_config,encoding='utf8') as fp:
        for _line in fp:
            if _user in _line:
                break
        _pat=re.compile(r'\s*"?SteamID"?\s+"?(\d+)')
        for _line in fp:
            if m:=_pat.match(_line):
                _steam_id = m[1]
                break
        else:
            raise ValueError("Unable to find SteamID.")
    _account_id=str(((1<<32)-1)&int(_steam_id))
    steam_write_folder=_steam_path.joinpath('userdata',_account_id,_game,'remote')
    steam_write_folder=os.path.abspath(steam_write_folder)

```
> 0 votes

---
Tags: steam
---


# Question
Title: Proper way to dynamically display a sprite on top of others in a Canvas
I'm trying to make the UI part of an inventory system which will involve the ability to move items from one slot to another, animating the item sprite going from one slot to the other.

Item slot prefabs initially had a UI Image component whose sprite property I used to display the item. An issue I had with that is that when moving items from one slot to another, the sprite would either appear on top or behind other items' sprites depending on (I assume) the hierarchy order of the slots to which they belong.

I tried looking around into how I could dynamically modify UI Image or sprite render priority, but solutions I found would either involve:

* Using a SpriteRenderer, which doesn't seem to be what UI Image use, meaning I have to add one in the prefab, and if I do that I might as well do away with UI Images in the first place and exclusively use them -\> This doesn't work, and it seems that SpriteRenderers aren't made to work in a Canvas? From what I've tried, it seems like the RectTransform used by Images and Transform used by the SpriteRenderer don't use the same coordinate system: if I give the same position to both, they would appear in different places, and the sprite would most likely be wayyy offscreen, unless I instead give it the same coordinates as another object visible in the scene.
* Using SortingGroup and sorting layers, which doesn't seem to work either for UI Images.
* Modifying the render order by modifying the order of objects in the hierarchy. This last one would I assume works, but feel kinda botchey and I can't imagine that relying on hierarchy order for drawing order couldn't lead to issues further down the line. Since currently each image is currently a child of an item slot gameobject, I can already see that it would likely also reorder the item slots themselves in my GridLayoutGroup, which would require further botching or rethinking everything to fix.
* Using multiple canvases so that one can give them different render priority. I'm not sure how it would go exactly, maybe two of the same size layered one and temporarily moving item slots from one canvas to the other for the duration of the sprite's movement? But this also feel very botchy.

I will eventually settle in for the hierarchy order method, but I feel like there is no way there isn't a better solution for this, unless that is my inexperience speaking and that solution is actually good.

My question is this: While not asking for a "best" solution, what would be one proper way to achieve this?

I am aware the formulation is kinda loaded, and maybe "do it by altering hierarchy order" could be a proper solution.

The version of Unity being used is 2021.2.2f1. If something is unclear, I can provide more information or reformulate.

# Answer
I don't know whether this solution is good or not, but here is what I did. Note that this could be simplified if you had the garantee that only one item could move at once. I do not know how viable this solution would be for a different usecase, for instance if numerous animations are expected to run very often.

I created a new Monobehavior class `ItemSlotAnimatorManager`, along with a regular class `ItemSlotAnimator`.

The logic for moving item images around was moved to `ItemSlotAnimator`s. One of those objects can only handle one animation at a time.

The `ItemSlotAnimatorManager` in the scene contains a pool of animators which it populates in Awake. For each animator it creates, it also instanciates a copy of my Item Sprite prefab, and passes its Image component to the animator which will use it.

The inventory UI can then use the manager to request an animation to be performed.

The manager keeps two lists of animators: One for idle animators, another for animators in use. Its Update loops through animators currently in use and calls their method to update them. The update method of animators returns `true` when the animation is over, which allows the manager to know which animators need to be returned to the idle animator list.

The GameObject which contains the `ItemSlotAnimatorManager` only needs to be placed below your inventory in your UI.

This solution will be limited by the number of animators in the pool, so this needs to be kept in mind - for instance by preventing the spamming of actions that trigger the animations, having a bit more animators than you think would be reasonably necessary, and defining behavior in case no animators are available.

Notes for decisions I took:

* Handling separate lists for idle and active animators, so you do not loop through idle animators for no reason during each Update, and you can just pop an idle animator when one is needed without having to search.
* Using a pool to prevent the creation and destruction of animator objects every time an animation occurs and finishes
* Maybe I could do away with the animator class and have one object handle as many animations as it wants, I have no idea if this would be more efficient, and I am not bothering.
> 2 votes

---
Tags: unity
---


# Question
Title: How do I render zones like Cities Skylines district tool?
I am trying to implement a zoning system like the district tool in Cities Skylines (see screenshot below). The player is able to draw/modify/erase zones with a brush tool. Internally, I represent each zone with a closed chain of vertices equally spaced out. I am new to computer graphics and game dev in general. I appreciate any pointer! :-)

1. How do I render the semi-transparent white overlay for each zone as in the screenshot? My current solution involves a dynamically generated mesh, with a semi-transparent material. Is there a better way?
2. How do I render the white bold edge of each zone?
3. How do I render the "sticki-ness" between the edges? As in, when two edges get too close, the game fills the tiny space between them with white color as well.

I'm using Unreal 5 if that matters.

# Answer
> 1 votes
I ended up applying an additive material on the dynamic polygon, such that I don't need to worry about the placement of the polygon and the weird glass-like refraction effect caused by semi-transparent material.

---
Tags: shaders, rendering, unreal-4, unreal
---


title: Vulkan shadow map artifacts

text:
# Question
Title: Vulkan shadow map artifacts
I am experiencing some weird shadow artifacts.

I suspect it to be some sort of self shadowing/depth bias thing.

My shader for the shadow map is quite simple:

`shadow_map.vert`

```
#version 450

layout(location = 0) in vec3 in_position;

layout(binding = 0) uniform uniform_scene {
  mat4 light_space;
} scene;

layout(push_constant) uniform uniform_object {
  mat4 model;
} object;

void main() {
  gl_Position = scene.light_space * object.model * vec4(in_position, 1.0);
}

```

`shadow_map.frag:`

```

#version 450

// layout(location = 0) out float out_depth;

void main() {
  // out_depth = gl_FragCoord.z;
}

```

And for actually doing the depth test for shadows I followed along learnopengl.com since I thought the shader code should be the same for vulkan and opengl.

`base.vert`

```
#version 450

struct per_mesh_data {
  mat4 model;
  mat4 normal;
  vec4 tint;
}; // struct per_mesh_data

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_uv;

layout(location = 0) out vec3 out_position;
layout(location = 1) out vec3 out_normal;
layout(location = 2) out vec2 out_uv;
layout(location = 3) out vec4 out_light_space_position;
layout(location = 4) out vec4 out_tint;

layout(binding = 0) uniform uniform_scene {
  mat4 view;
  mat4 projection;
  vec3 camera_position;
  mat4 light_space;
  vec3 light_direction;
  vec4 light_color;
} scene;

layout(binding = 1) buffer buffer_mesh_data {
  per_mesh_data data[];
} mesh_data;

const mat4 depth_bias = mat4(
    0.5, 0.0, 0.0, 0.0,
    0.0, 0.5, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.5, 0.5, 0.0, 1.0
);

void main() {
  per_mesh_data data = mesh_data.data[gl_InstanceIndex];

  out_position = vec3(data.model * vec4(in_position, 1.0));
  out_normal = normalize(mat3(data.normal) * in_normal);
  out_uv = in_uv;
  out_light_space_position = (depth_bias * scene.light_space) * vec4(out_position, 1.0);
  out_tint = data.tint;

  gl_Position = scene.projection * scene.view * vec4(out_position, 1.0);
}

```

`base.frag`

```

#version 450

#include "../common/lighting.glsl"
#include "../common/material.glsl"

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_uv;
layout(location = 3) in vec4 in_light_space_position;
layout(location = 4) in vec4 in_tint;

layout(location = 0) out vec4 out_color;

layout(binding = 0) uniform uniform_scene {
  mat4 view;
  mat4 projection;
  vec3 camera_position;
  mat4 light_space;
  vec3 light_direction;
  vec4 light_color;
} scene;

layout(binding = 2) uniform sampler2D image;
layout(binding = 3) uniform sampler2D shadow_map;

layout(push_constant) uniform uniform_object {
  mat4 model;
  mat4 normal;
} object;

const material default_material = material(
  vec4(1.0, 1.0, 1.0, 1.0),
  vec4(1.0, 1.0, 1.0, 1.0),
  vec4(0.5, 0.5, 0.5, 1.0),
  16.0
);

vec4 phong_lighting(vec3 light_direction, vec3 view_direction, vec3 normal, material material) {
  // Ambient
  vec4 ambient_color = scene.light_color * material.ambient;

  // Diffuse
  float diffuse_factor = max(dot(light_direction, normal), 0.0);
  vec4 diffuse_color = diffuse_factor * scene.light_color * material.diffuse;

  // Specular
  vec3 halfway_direction = normalize(light_direction + view_direction);
  float specular_factor = pow(max(dot(normal, halfway_direction), 0.0), material.shininess);
  vec4 specular_color = specular_factor * scene.light_color * material.specular;

  return ambient_color + diffuse_color + specular_color;
}

float pcf_shadow(vec3 light_direction) {
  vec2 texture_size = textureSize(shadow_map, 0);
  vec2 texel_size = 1.0 / texture_size;

  vec3 coordinates = in_light_space_position.xyz / in_light_space_position.w;

  if (coordinates.z > 1.0 || coordinates.z < -1.0) {
    return 0.0;
  }

  float shadow = 0.0;

  float bias = max(0.001 * (1.0 - dot(in_normal, light_direction)), 0.0001);
  // float bias = 0.001;

  float current_depth = coordinates.z;

  int count = 0;
  int range = 2;

  for (int x = -range; x <= range; ++x) {
    for (int y = -range; y <= range; ++y) {
      float pcf_depth = texture(shadow_map, coordinates.xy + vec2(x, y) * texel_size).r;
      shadow += (current_depth - bias) > pcf_depth ? 1.0 : 0.0;
      ++count;
    }
  }

  return shadow / float(count);
}

void main() {
  vec3 light_direction = normalize(-scene.light_direction);
  vec3 view_direction = normalize(scene.camera_position - in_position);

  // Calculate lighting
  vec4 lighting = phong_lighting(light_direction, view_direction, in_normal, default_material);

  // Calculate shadow
  float shadow_factor = pcf_shadow(light_direction);

  // Sample texture
  vec4 sampled_color = texture(image, in_uv);

  vec4 shaded_lighting = mix(lighting * (1.0 - shadow_factor), lighting * 0.2, shadow_factor);

  out_color = shaded_lighting * sampled_color * in_tint;
}

```

The included files here just define structs like `material` and `directional_light`

# Answer
If you give the "float bias" variable large constant values? Does it go away? First make sure that bias variable has any effect. If so, then you have two places where you can adjust bias. You can adjust in shader with your existing code which tries to deal with the steep angled surface bias (thats your problem based on the screenshots). Or you can set it in the VkPipelineRasterizationStateCreateInfo, where you can set slope variable as well: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineRasterizationStateCreateInfo.html

The latter is equivalent to the glPolygonOffset but with slope factor which shifts the polygons a bit which helps to eliminate the self shadow issues.

All in all, self shadow elimination is a parameter tuning game, between shadow acne or peter panning artifacts. Variance shadow map technique can help this, which will both solve the hard edges, shimmering, and shadow acne issues.
> 1 votes

---
Tags: c++, glsl, vulkan
---


title: KeyCode field in custom inspector

text:
# Question
Title: KeyCode field in custom inspector
I'm making a custom inspector for my script, and I have an option to pick a KeyCode as you can see below

However, now that I'm using a custom inspector, I don't know how to add a Keycode Field. I *assumed* it would be like the rest of the custom objects, where you would just use `EditorGUILayout.ObjectField()` but since KeyCode doesn't derive from `UnityEngine.Object` it doesn't work.

I've tried researching, but all I can find are posts on how to detect keypresses in the custom inspector. Does anyone have a solution?

# Answer
I found you can just use a cast along with an EnumPopup, like this:

```
_defaultInteractionKey = (KeyCode)EditorGUILayout.EnumPopup("Default Interaction Key", _defaultInteractionKey);

```
> 1 votes

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


# Question
Title: How to smooth out jagged stair step edges between polygons?
Working on a simple board game. The game renders the board with jagged lines.

The models were built in Blender. Everything is .obj. The White part and the border are separate objects.

I've tried increasing resolution and increasing poly count on the objects but it is still rendered with jagged lines.

Is there a way to sharpen the lines? Either in Blender or Godot?

# Answer
> 1 votes
Answer provided by Mangata in the comments to the original post.

**Note**: the information within was tested within Godot 4.0. I Can't speak to earlier versions.

The solution was to implement anti-aliasing. Information outlined in this article: https://docs.godotengine.org/en/stable/tutorials/3d/3d\_antialiasing.html

Specifically, from within project settings, enable advanced settings:

Then in the navigation tree on the left, expand the rendering group and locate Anti-Aliasing:

I elected to use MSAA 3D 8x originally but down-scaled to 4x for performance.

Result:

---
Tags: rendering, godot, antialiasing
---


# Question
Title: Detect collisions with both parent and child nodes in Godot
Using Godot 4.2.1, I have a 3D scene with a CharacterBody3D as the root. It has two children; a child CollisionShape3D, and a child CharacterBody3D with its own collision shape.

```
CharacterBody3D (scene root)
    CollisionShape3D (parent collision shape)
    CharacterBody3D (child)
        CollisionShape3D (child collision shape)

```

The scene root has a script which calls `MoveAndSlide` in `PhysicsProcess()`. It works fine for the parent and its collision shape, if you hit an obstacle, the parent stops moving. However I would like the parent to stop moving also if the child shape hits an obstacle, and that is not happening.

The child is not being moved manually through scripts, it's only being taken along with the parent's movement. I tried changing it to a StaticBody3D too, but the issue persists. The collision layers and masks are the same for both parent and child; if that was wrong, the collision wouldn't work for either.

How can I get the child's collision to be detected? And the movement to stop even when the child collides, same as the parent? Is there a solution that handles this issue even when the child is instantiated at runtime, through scripts?

# Answer
> 0 votes
I'm having a hard time visualizing what you mean.

From what I've seen in Godot, if movement is not controlled by the built in functions (like moveAndSlide()) collisions are not checked. So if the child is being dragged with the parent the child collisions likely aren't checked.

Something you can try to do is to use signals so that when the parent moves, a signal is fired. The signal would contain a vector indicating the movement expected of the child and then the child would respond to the signal by calling moveAndSlide() with the supplied vector.

I think the only challenge would be suppressing the child's native behavior of being dragged with the parent. The easy way to do this is not add it as a child to the parent but rather a sibling.

You can connect signals on dynamically instantiated objects. This is some c# code I use to do this but I believe this can also be done in GDScript:

```
PackedScene cellResource = ResourceLoader.Load<PackedScene>("res://TicTacToe/Scenes/GameBoard/Cell.tscn");
Godot.StringName signalName = new Godot.StringName("cellClicked");
Godot.Callable signalHandler = new Godot.Callable(this, MethodName.onCellClicked);
Cell cell = cellResource.Instantiate<Cell>();
cell.Connect(signalName, signalHandler);

```

Here's an answer on StackOverflow that I think does a great job at explaining collision: https://stackoverflow.com/questions/69728827/how-do-i-detect-collisions-in-godot

It does still emphasize the use of collision signals or the use of moveAndSlide/moveAndCollide functions.

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


# Question
Title: Make attack particles at collision point?
I'm working on a 2D game, it has some basic combat but I want to spice it up a bit with some effects.

First I added a flash when you get hit but I also wanted to add some particles. I thought it would be easy and I could just put the particles at the enemy's or player's position. But it didnt look right.

So does anyone know how I can detect the position I collided? I'm using PhysicsOverlapCircleAll to detect the enemys.

# Answer
> 2 votes
`Physics2D.OverlapCircle` doesn't provide you that information on where exactly the overlap happened.

But there are other options you could do instead:

* Do the collision detection for attacks using rigidbody collisions handled via the `OnCollisionEnter2D` method. The Collision2D object passed to this method contains an array of contact positions. Handling attacks as a rigidbody hitting other rigidbodies also has the neat effect that it's an easy way to add physically accurate pushback if you want to, which is another way to add more "juice" to a game. (although in a way that is not just cosmetic but actually affects the mechanics of the game)
* After detecting that there is a collision with PhysicsOverlapCircle, use `Physics2D.ClosestPoint` from the attacker's position to the target collider to get the closest point on the perimeter of their collider.
* After detecting that there is a collision with PhysicsOverlapCircle, use a `Physics2D.Raycast` from the attacker to the target. The returned RaycastHit2D object contains the .point where the contact occurred. It also provides a .normal that can be useful for setting the orientation of a hit particle effect.

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


# Question
Title: Finding the index in a material where a raycast hit
I have a gameobject with a mesh collider. The mesh is simply a flat plane.

I raycast to the mesh and I'd like to get the index on the material's basemap where I got a hit.

I assumed `hit.textureCoord` or `hit.textureCoord2` would do the trick, but all I get is either `(0,0)` or `(1,1)` and nothing inbetween.

I triple checked and the collider is definitely a mesh collider, so I can only assume I misunderstood what `textureCoord` does

# Answer
Apparently I misunderstood what `hit.textureCoord` does. Since the mesh I was dealing with had only 4 vertices and 2 triangles (a simple plane), it can only return `(0,0)` or `(1,1)`, for each of the two triangles.

In general, `hit.textureCoord` seems to return a vector2 associated with the triangle hit, rather than anything to do with the basemap on the material itself.
> 0 votes

---
Tags: unity, raycasting
---


# Question
Title: Trouble setting camera position in Unity
I'm attempting to set the camera position in Unity through code. I have a simple 2D game and there's not much programming so far. I've attached a script to the camera, and in that script I've added this function:

```
  void Update()
    {
    Transform transform = gameObject.GetComponent<Transform>();
    Vector3 position = transform.position;
    transform.position.Set(position.x + 1, position.y + 1, position.z);
    }

```

My expectation is that this would create a smooth scrolling toward the bottom right corner. However, after checking via breakpoints, the transform.position always reports (0, 0, -10), even after setting it. The camera object is a stand alone and not a child of anything else in the scene. Am I setting the position wrong or getting the camera's GameObject wrong?

I've also tried:

* transform.SetPosition(); - doesn't exist
* transform.SetPositionAndRotation(); - no effect
* transform.position.x = 0; - not allowed
* transform.position = new Vector3(position.x + 1, position.y + 1, position.z) - no effect

# Answer
There are several misconceptions here.

First off, every `Component` and `GameObject` already has a pre-cached `transform`, property, so you *never* have to write `GetComponent<Transform>()`. Deleting this line changes nothing, since all it does is shadow the existing `transform` property that gives the same value:

```
Transform transform = gameObject.GetComponent<Transform>();

```

Next, `transform.position` is a *getter/setter* property. When you read or write to it, you're really calling a function. The getter you call on a read...

1. Takes the transform's internally stored local position...
2. Gets the corresponding world position by transforming it by any transformations higher up in the hierarchy...
3. Returns to you a *copy* of that value.

Calling `position.Set()` on a *copy* of the data does not make the change propagate back to the original transform: it has no idea you changed anything, because you didn't ask *it* to change.

Thirdly, you never want to add a constant offset to a position in `Update()`, because that function is called at a variable framerate. To get smooth motion, you should scale the movement by the amount of time elapsed since the previous `Update()` frame.

Lastly, moving +1 in y is moving up, not down, in Unity's coordinate system. If you want to move down, *decrease* y.

Putting these together:

```
public float movementSpeed = 1f;

void Update() {
    Vector3 position = transform.position;
    Vector3 shift = new Vector3(1, -1, 0) * movementSpeed * Time.deltaTime;
    transform.position = position + shift;

    // Or, as another answer notes,
    // transform.Translate(shift, Space.World)
    // accomplishes the same thing.
}

```
> 4 votes

# Answer
Try: `transform.Translate(movement_dir)` where `movement_dir` is a vector you can define outside of `Update` if it's going to be a constant.

However you might want to multiply `movement_dir` by `Time.deltaTime`, otherwise it might not be as smooth as you'd like due to variations in FPS

see this
> 0 votes

---
Tags: unity, 2d, camera, position
---


# Question
Title: Is there an existing Quadtree implementation in libGDX?
I've seen a lot of sites that recommends to use Quadtree for splitting the array by levels and nodes for a better performance for example in `CollisionSystem` there's a lot of collisions needs to be handle. I need to ask this question because I'm planning to create my own `Quadtree` class, if there it didn't exist.

# Answer
GDX doesn't support it directly.

A version for LibGDX https://github.com/alwex/QuadTree
> 2 votes

# Answer
A bit late but here is an implementation that is specifically developed for use with libgdx: https://github.com/nahumrosillo/quadtree-libgdx
> 0 votes

---
Tags: libgdx, quadtree
---


# Question
Title: inserting 3d .obj into scene with godot code
I am trying to write some code, where upon running it will place a 3d obj. It is a tool to help build a map before game runtine.

It is a simple 3d obj arrayMesh I am trying to add to a tscn file.

In godot I have:

```
@tool
extends EditorScript

# scene to 3d obj to
var scene = preload("res://main.tscn").instantiate()

# load 3d pbject
var grass = preload("res://map/Models/OBJ format/grass.obj")

func _run():
    # get node to append map to
    var map_holder_node = scene.get_node("map_holder")

    map_holder_node.add_child(grass.new())

```

I get the error:

```
res://map/generate_map.gd:14 - Invalid call. Nonexistent function 'new' in base 'ArrayMesh'.

```

Any ideas?

# Answer
Anything you `load` or `preload` is a `Resource`. That includes, for example, `PackedScene`, which you `instantiate`, and `Script`s which you usually create with `new` (in general you create instances of classes with `new`, and `Script`s are classes).

In this case you have an `ArrayMesh`, which is neither a `PackedScene` nor a `Script`.

I understand you want some `Node`, given that you are trying to use `add_child`. So the question is: what kind of `Node` can hold a `ArrayMesh`?

I want to highlight that Godot is not making assumptions about how `Resource`s will be used. For example, you could create a script that exports a variable of `ArrayMesh` so you can set it. However, I don't think that is what you want.

Well, `ArrayMesh` is a kind of `Mesh`, and here are three build-in `Node` types that can use it: `CSGMesh3D`, `GPUParticles3D` and `MeshInstance3D`.

The most usual case is `MeshInstance3D`, which you create and then set its`mesh` property:

```
    var mesh_instance := MeshInstance3D.new()
    mesh_instance.mesh = grass
    map_holder_node.add_child(mesh_instance)

```

You might want to set other of the properties of `MeshInstance3D`, but I cannot guess which or how.

And, of course, using the `ArrayMesh` directly in a `Node` is not the only thing you can do with it. For example, you might use it to create other resources... Notably, you might be interested in `MultiMesh`.
> 3 votes

---
Tags: godot
---


title: Add wobblyness to moving object

text:
# Question
Title: Add wobblyness to moving object
I've been working on a custom enemy "AI", the way it works is it generates a point inside a colliders bounds, then moves the enemy towards the point. Once the enemy reaches it. The point is generated in a random different place. Kinda giving the effect that it's flying around randomly.

The only posts and information I could find was removing wobbling or stuttering. I thought maybe I could use some Perlin Noise and then add it as like an offset. But I couldn't figure out a way to do it well. So does anyone know how I can add an offset using Perlin noise? The solution cant just add a random offset otherwise it just jitters around, it has to be a smooth wobble. That's the part that I'm finding difficult.

Here is my code (with some unnecessary parts cutout):

```
[Header("Enemy Settings")]
public EnemyType enemyType;
public float speed;
public float maxDistance;

[Header("Flight Settings")]
public BoxCollider2D flightBounds;
public Transform flightBoundsPosition;
public bool stationaryWhenIdle;

[Header("Attack Settings")]
public EnemyAttackType attackType;
public EnemyAgression enemyAgression;
public float playerDetectionRadius;
public LayerMask playerLayer;

public float playerFollowSpeed;
public float chargeForce;
public float chargeDuration;
public float chargeCooldown;

// internals
private Rigidbody2D rb;
private Bounds boxBounds;
bool atPoint = false;
Vector2 point;
int dir;

void Update() {
    if (enemyType == EnemyType.Walking) {
        FlipEnemy();
        MoveEnemy(EnemyType.Walking);
        AlignEnemy();
    }
    if (enemyType == EnemyType.Flying) {
        FlipEnemy();
        MoveEnemy(EnemyType.Flying);
        AlignEnemy();
    }
}

private void MoveEnemy(EnemyType type) {
    if (type == EnemyType.Flying) {
        // flight
        if (!stationaryWhenIdle) {
            point = GeneratePoint(false);
            float step = speed * Time.deltaTime;
            transform.position = Vector2.MoveTowards(transform.position, point, step);
        }

        // attack
        if (enemyAgression == EnemyAgression.Passive) return;
        Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(transform.position, playerDetectionRadius, playerLayer);
        foreach (Collider2D col in collider2Ds) {
            if (attackType == EnemyAttackType.Follow) {
                float step = playerFollowSpeed * Time.deltaTime;
                transform.position = Vector2.MoveTowards(transform.position, col.transform.position, step);
                break;
            }
        }
    }
    else {
        rb.velocity = new Vector2(speed * dir, rb.velocity.y);
    }
}

private Vector2 GeneratePoint(bool isStart) {
    if (Vector2.Distance(transform.position, point) < 0.2f) atPoint = true;
    else atPoint = false;
    if (atPoint || isStart) {
        Vector2 position = new Vector2(
            Random.Range(boxBounds.min.x, boxBounds.max.x),
            Random.Range(boxBounds.min.y, boxBounds.max.y)
        );
        return position;
    }
    else return point;
}

```

# Answer
> 2 votes
When I want to make an object "wobble" in a way that looks natural and fluent, then my go-to solution is to use sine waves. Using different frequencies for different axis, and probably layering a couple different curves with different amplitudes and frequencies might not actually be random but it looks pretty chaotic to the player.

Here is an example script that uses two separate sine waves with separate frequency and amplitude, one for the x axis and one for the y axis.

It does that by setting the `localPosition`. The Idea is that you parent the visual object with this script to an invisible parent. The parent has the position where the object is *supposed* to be, while the `Wobble`-script makes the visible object wobble around that position.

```
using UnityEngine;

public class Wobble : MonoBehaviour {

    public float xFrequency = 4.1f;
    public float xAmplitude = 1.0f;
    public float yFrequency = 4.3f;
    public float yAmplitude = 1.0f;

    void Update()
    {
        transform.localPosition = new Vector3(
            Mathf.Sin(Time.time * xFrequency) * xAmplitude,
            Mathf.Sin(Time.time * yFrequency) * yAmplitude,
            0f
        );
    }
}

```

Result:

If you want the wobble to look more random, then you can layer some more sine waves with different frequencies and amplitudes. Here is a script that allows you to define as many waves for the x and y axis as you want:

```
using System;
using UnityEngine;

public class Wobble : MonoBehaviour {

    [Serializable]
    public struct SineWave {
        public float frequency;
        public float amplitude;
        public float Resolve() {
            return Mathf.Sin(Time.time * frequency) * amplitude;
        }
    }

    public SineWave[] xWaves;
    public SineWave[] yWaves;

    void Update()
    {
        float x = 0f;
        foreach (var xWave in xWaves) {
            x += xWave.Resolve();
        }
        float y = 0f;
        foreach (var yWave in yWaves) {
            y += yWave.Resolve();
        }

        transform.localPosition = new Vector3(x, y, 0f);
    }
}

```

Here is a result with 3 different waves per axis:

# Answer
> 2 votes
## Performant Random Noise

Perlin Noise can be a rather slow calculation. If you need to apply to many objects it would be prohibitively slow.

You can use a pseudo random number (PRN) generator to sample a random sequence seeding the sequence at regular interval/locations to smooth and repeat the result.

PRNs are fast and repeatable.

This can give you deterministic yet random looking behaviours. The PRN below appears very similar to perlin noise (pink noise) but does not have the fixed frequency spread of perlin (Example PRN is white noise ignoring the sample frequence)

### Example of PRN generator

Very simple random number generator. For humans it looks very random, for machines not so much.

```
const double MAX = 2576436549074795;
const double INV_MAX = 1.0 / MAX;
double RandUnit(double seed) { // return unit value 0.0 <= RandUnit(seed) < 1.0
    seed = Math.floor(seed );
    return (((8765432352450986.0 * seed) + 8507698654323524.0) % MAX) * INV_MAX;
}

```

### Example of noise function using above PRN

```
// One dimension time based noise
// time in seconds,
// freq in changes per second
// returns unit double 0.0 <= Noise() < 1.0
double Noise(double time, double freq) {
    const double randLow = RandUnit(Math.floor(time * freq));
    const double randHi  = RandUnit(Math.floor(time * freq) + 1.0);
    return (randHi - randLow) * ((time * freq) % 1) + randLow;
}

```

The above noise function would replace the perlin noise function.

The noise and random functions return unit values that are easily scaled and used to lerp values you wish to add noise to.

## Example

Below is a runnable example written in JavaScript. It is a example proof of concept for you. Not too hard to convert to C#.

It has two core functions that you will need.

* `RandFloat(seed)` which returns a random unit value (0 to 1) based on the `seed` value.

**NOTE** that the example is using doubles 64bit forced to integer. Scale the magic numbers to fit floats if using 32bit values
* `Noise(time, freq, useEase)` which uses `RandFloat` to return a unit noise value based on `time` and desired `freq`uency.

**NOTE** The bool `useEase` if true will add a in out ease on the unit value (Big dots in example have smoothed (eased) noise)

The example create a set of moving objects each with a position and velocity.

Each object is also given a noise frequency (in seconds) and a noise amplitude (scale in pixels)

Noise is added perpendicular to velocity.

The objects move via a global delta time, and the noise position is based on time as with your example code. Each object is shadowed by a lighter circle showing the position it would be without the noise applied.

```
requestAnimationFrame(MainLoop);
const OBJECT_DESITY = 0.001;   // Objects per canvas pixels squared
const NOISE_SCALE_MIN = 10;    // In pixels
const NOISE_SCALE_MAX = 23;    // In pixels
const NOISE_FREQ_MIN = 1;      // per second
const NOISE_FREQ_MAX = 4;      // per second
const MIN_SPEED = 5;           // Object speed in pixels per second
const MAX_SPEED = 10;          // Object speed in pixels per second
const objects = [];
const INV_MS_PER_SEC = 1/1000;
var time;
const ctx = canvas.getContext("2d");

const eCurve   = (v, p = 2, vp) =>  v < 0 ? 0 : v > 1 ? 1 : (vp = v ** p) / (vp + (1 - v) ** p);
const RanRan = (min, max) => Math.random() * (max - min) + min;
const V2 = (x = 0, y = 0) => ({x, y});
const InvLength = (v2) => 1 / (v2.x * v2.x + v2.y * v2.y) ** 0.5;
const Normalize = (v2, res = V2()) => {
  const invLen = InvLength(v2);
  res.x = v2.x * invLen;
  res.y = v2.y * invLen;
  return res;
}

const RandFloat = (() => {
    var seed = 1;
    const MAX = 2576436549074795;
    const INV_MAX = 1 / MAX;
    return  (s = seed) => {
        seed = Math.floor(s);
        return (seed = ((8765432352450986 * seed) + 8507698654323524) % MAX) * INV_MAX;
    }

})();
function Noise(time, freq, useEase) {
    const t = time * freq;
    const tLow = Math.floor(t);
    const tHi = tLow + 1;
    const tFrac = t % 1;
    const randLow = RandFloat(tLow);
    const randHi  = RandFloat(tHi);
    return (randHi - randLow) * (useEase ? eCurve(tFrac) : tFrac) + randLow;
}

const CreateObj = () => {
    const dir = RanRan(0, Math.PI * 2);
    const speed = RanRan(MIN_SPEED, MAX_SPEED);
    const id = objects.length;
    const radius = id % 2 ? 4 : 3; // smooth random larger objects

    return {
        pos: V2(RanRan(0, ctx.canvas.width), RanRan(0, ctx.canvas.height)),
        nPos: V2(),
        vel: V2(Math.cos(dir) * speed, Math.sin(dir) * speed),
        noiseFreq: RanRan(NOISE_FREQ_MIN, NOISE_FREQ_MAX),
        noiseScale: RanRan(NOISE_SCALE_MIN, NOISE_SCALE_MAX),
        Update(deltaTime) {
            this.pos.x += this.vel.x * deltaTime;
            this.pos.y += this.vel.y * deltaTime;
            const perp = Normalize(this.vel);
            const noise = Noise(time * INV_MS_PER_SEC, this.noiseFreq, id % 2) - 0.5;
            this.nPos.x = this.pos.x + -perp.y * noise * this.noiseScale;
            this.nPos.y = this.pos.y +  perp.x * noise * this.noiseScale;
        },
        Draw() {

            const x = ((this.pos.x + 4) % (canvas.width + 8)) - 4;
            const y = ((this.pos.y + 4) % (canvas.height + 8)) - 4;
            ctx.moveTo(x + radius, y);
            ctx.arc(x, y, radius, 0, Math.PI * 2);
        },
        DrawRnd() {
            const x = ((this.nPos.x + 4) % (canvas.width + 8)) - 4;
            const y = ((this.nPos.y + 4) % (canvas.height + 8)) - 4;
            ctx.moveTo(x + radius, y);
            ctx.arc(x, y, radius, 0, Math.PI * 2);
        },
    };
}
function Resize() {
    canvas.width = innerWidth;
    canvas.height = innerHeight;
    objects.length = 0;
    var i = Math.floor(Math.min(5000, OBJECT_DESITY * canvas.width * canvas.height));
    info.innerText = "Object count: " + i;
    while (i-- > 0) { objects.push(CreateObj()); }
}

function MainLoop(timeNow) {
    if (canvas.width !== innerWidth || canvas.height !== innerHeight) {
        Resize();
    }
    if (time == undefined) {
        time = timeNow;
    }
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    const deltaTime = (timeNow - time) * INV_MS_PER_SEC;
    for (const obj of objects) { obj.Update(deltaTime); }

    ctx.fillStyle = "#0002";
    ctx.beginPath();
    for (const obj of objects) { obj.Draw(); }
    ctx.fill();

    ctx.fillStyle = "#0009";
    ctx.beginPath();
    for (const obj of objects) { obj.DrawRnd(); }
    ctx.fill();
    time = timeNow;
    requestAnimationFrame(MainLoop);

}
```

```
canvas {
    position: absolute;
    top: 0px;
    left: 0px;
}
div {
    position: absolute;
    top: 20px;
    left: 20px;
    color: red;
    background: white;
    font-family: arial black;
}
```

```
<canvas id="canvas" width="1" height="1"></canvas>
<div id="info"></div>
```

# Answer
> 0 votes
I figured it out, You can just generate some Perlin noise using the time like this:

```
float noise = Mathf.PerlinNoise(Time.time, Time.time);

```

Then apply it to the moving objects y axis:

```
transform.position += new Vector3(0, noise, 0)

```

The only downside is there's no way to change the noise scale, it works fine anyway though.

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


# Question
Title: Identifying extreme vertices for shadow effects in 2D game using JavaScript
I'm facing an issue while trying to identify the two most extreme vertices of an object in my 2D game using JavaScript. The goal is to determine where I should create a trapezoid to simulate the shadow casting.

Currently, my approach involves rotating the object's vertices to the same plane as the light and then selecting the vertices with the highest and lowest Y values. However, this isn't working as expected, as I end up consistently selecting the diagonal vertices.

I thought about selecting the vertices with the greatest difference in angles relative to the light to determine which ones are the boundary vertices of the object, but I couldn't get it right.

Github repository: https://github.com/markvaaz/game-engine/tree/Renderer

**Here's a snippet of my attempt to create the method within my LightingManager class:**

```
  /**
   * Gets the extremes of the shape in relation to the plane of the angle between the light and the shape
   * @param {Object} shape
   * @param {Object} light
   * @method getVerticesFromExtremes
   */
  getVerticesFromExtremes(shape, light){
    const { position: center, vertices } = shape;
    const { position } = light;
    const angle = new Vector(position).angleBetween(center);
    let minIndex = 0;
    let maxIndex = 0;

    vertices.forEach((vertex, index) => {
      vertex = new Vector(vertex.x, vertex.y);
      vertex.rotate(-angle);

      if(vertex.y < vertices[minIndex].y){
        minIndex = index;
      }

      if(vertex.y > vertices[maxIndex].y){
        maxIndex = index;
      }
    });

    if(minIndex > maxIndex) return {
      min: maxIndex,
      max: minIndex
    }

    return {
      min: minIndex,
      max: maxIndex
    }
  }

```

**Here's an example image illustrating the desired shadow effect achieved by selecting the two most extreme points:**

For testing purposes, I'm using the following vertex coordinates for a rectangle:

```
[ { "x": -32, "y": -41 }, { "x": 32, "y": -41 }, { "x": 32, "y": 41 }, { "x": -32, "y": 41 } ]

```

> Note that the coordinates belong to the shape, and the global position is not included. The shape's global position is indicated by the 'position' property of the shape. The light position is its global position

**This is the light object and its properties:**

```
{
  "enabled": true,
  "mode": "lighter",
  "brightness": 1,
  "radius": 250,
  "type": "cone",
  "position": {
    "x": 722.5,
    "y": 413.9
  },
  "steps": [
    {
      "start": 1,
      "color": "rgba(255, 255, 255, 0.8)"
    },
    {
      "start": 0,
      "color": "transparent"
    }
  ],
  "angle": 0.0006666665679014124,
  "distance": 150.0000333333296
}

```

**EDIT: DMGregory's answer works up to a certain distance from the object; however, upon getting closer, it ends up selecting the wrong vertex.**

# Answer
I revamped the method to calculate the angles between the light source and each vertex, and then selecting the vertices with the smallest and largest angles. This way, you get the vertices that are at the extremes in relation to the light, regardless of the angle.

```
getVerticesFromExtremes(shape, light, shapePosition) {
    // If the shape has no vertices, return false
    if(shape.vertices.length === 0) return false;

    // Destructure the vertices from the shape
    const { vertices } = shape;
    // Define the center position of the shape and the position of the light
    const center = shapePosition;
    const position = light.position;

    // Initialize the minimum and maximum angles to extreme values
    let minAngle = Infinity;
    let maxAngle = -Infinity;

    // Initialize the indices of the minimum and maximum angles to -1
    let minIndex = -1;
    let maxIndex = -1;

    for(let index = 0; index < vertices.length; index++){
      // Calculate the position of the current vertex
      const vertex = {
        x: vertices[index].x + center.x,
        y: vertices[index].y + center.y
      };

      // Create vectors from the light source to the vertex and the center of the shape
      const vectorToVertex = new Vector(vertex.x - position.x, vertex.y - position.y);
      const vectorToCenter = new Vector(center.x - position.x, center.y - position.y);

      // Calculate the difference between the angles
      let angle = Math.atan2(vectorToVertex.y, vectorToVertex.x) - Math.atan2(vectorToCenter.y, vectorToCenter.x);

      // Normalize the angle to be within the range [-PI, PI]
      if (angle < -Math.PI) {
        angle += Math.PI * 2;
      }

      if (angle > Math.PI) {
        angle -= Math.PI * 2;
      }

      // Update the minimum and maximum angles and their corresponding indices
      if (angle < minAngle) {
        minAngle = angle;
        minIndex = index;
      }

      if (angle > maxAngle) {
        maxAngle = angle;
        maxIndex = index;
      }
    }

    // Return the indices of the vertices with the minimum and maximum angles
    return { min: minIndex, max: maxIndex }
  }

```
> 2 votes

# Answer
If your light cone is consistently less than 180 degrees, you can get away with sorting the vertices in the order of the slope of the rays joining them to the light, without any trigonometry:

```
  getVerticesFromExtremes(shape, light) {
    const { center, vertices } = shape;
    const { position } = light;

    // Construct a vector pointing from the light to the object.
    const axis = new Vector(center.x - position.x, center.y - position.y);

    // Compute offsets to center the light in this axis-oriented coordinates system.
    const onShift = position.x * axis.x + position.y * axis.y;
    const offShift = position.x * axis.y - position.y * axis.x;

    let minSlope = Infinity;
    let maxSlope = -Infinity;

    let minIndex = 0;
    let maxIndex = 0;

    for(let index = 0; index < vertices.length; index++){
      const vertex = {
        x: vertices[index].x + center.x,
        y: vertices[index].y + center.y
      };

      // Add the shape's global position to the vertex

      // Put this vertex into a light-centered coordinate system.
      // First, measuring its (scaled) distance in front of the light:
      const onAxis = vertex.x * axis.x + vertex.y * axis.y - onShift;

      // Skip vertices behind / in the plane of the light.
      if (onAxis <= 0) return;

      // Then measuring its (scaled) offset above or below the line through
      // the center of this object.
      const offAxis = vertex.x * axis.y - vertex.y * axis.x - offShift;

      // Compute the slope of the line from the light to the vertex.
      const slope = offAxis / onAxis;

      if (slope < minSlope) {
          minSlope = slope;
          minIndex = index;
      }

      if (slope > maxSlope) {
          maxSlope = slope;
          maxIndex = index;
      }
    }

    if(minIndex > maxIndex) return {
      min: maxIndex,
      max: minIndex
    }

    return {
      min: minIndex,
      max: maxIndex
    }
  }

```

This gets more complicated if you have a light with a \> 180 degree span though, or complex shapes that can wrap around the light, so the object's center is on one side, but some occluding vertices might be on the other.
> 1 votes

# Answer
The best solution would need to know more about the objects you are trying to find the extremes for.

Things like,

* are the shapes always convex,
* is there any symmetry,
* do lines intercept self,
* and more

## Simple convex shape

The simplest solution is to get the vector from each point to the light and then compare the cross product between adjacent vectors.

Calculate the cross product for adjacent clockwise and anticlockwise points.

For cross products \< 0 clockwise next point is more extreme, and anticlockwise cross product is \> 0 for more extreme (I think that is the right way around, if not just swap the signs)

This only works for convex shapes. To do it for concave shapes you are best off breaking the object into a set of convex shapes.

This only works if the light is outside the shape.

## The Function

The function `FindExtrema(light)` that finds the extremes.

* Note there is NO trig required.
* Complexity is O(n) where n is number on points defining the shape.

```
    // this.verts[] set of 2d points for shape
    // light 2D pos of light
    // V2 creates 2D vector
    FindExtrema(light) {
        const left = V2().set(light).sub(this.pos); // from center to light
        const right = V2().set(left);  // for right edge
        const wV = V2();               // working vector
        this.leftVertIdx = -1;         // left index
        this.rightVertIdx = -1;        // right index
        var i = 0, c;
        for (const tV of this.verts) { // Each point in turn
            wV.set(tV).sub(light);     // vector from light to point
            c = left.cross(wV);        // cross product with prev left
            if (c < 0) {               // Is left of prev left
                this.leftVertIdx = i;  // Yes save idx
                left.set(wV).neg();    // set new left (swap dir)
            }
            c = right.cross(wV);       // same for right extreme
            if (c > 0) {
                this.rightVertIdx = i;
                right.set(wV).neg();
            }
            i++;
        }
    }

```

## Example

The snippet shows this simple method of getting the extrema for a shape.

Move mouse to move shape.

Press the mouse button to get a random shape. You will note that the solution will not work for concave shapes.

The function `Shape.FindExtrema(from)` finds the left and right extreme points when looking at the object from the 2D vector `from`.

The points are referenced by their index as `Shape.leftVertIdx` and `Shape.rightVertIdx`

The shape transforms the base shape. It is the transformed points that are used to find the left and right edges.

If you have problems ask in the comments.

```
const ctx = canvas.getContext("2d");
var W = canvas.width, H = canvas.height, resized = false;
const TAU = Math.PI * 2;
const Resize = () => { W = canvas.width = innerWidth; H = canvas.height = innerHeight; resized = true; }
const mouse  = {x : 0, y : 0, button : false}
function mouseEvents(e){
    mouse.x = e.pageX; mouse.y = e.pageY;
    mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
}
["mousedown","mouseup","mousemove"].forEach(name => document.addEventListener(name,mouseEvents));

const V2 = (x = 0, y = 0) => ({
    x, y,
    set(v) { this.x = v.x; this.y = v.y; return this; },
    sub(v) { this.x -= v.x; this.y -= v.y; return this; },
    length() { return (this.x * this.x + this.y * this.y) ** 0.5; },
    normalize(len = this.length()) { this.x /= len; this.y /= len; return this; },
    neg() { this.x = -this.x; this.y = -this.y; return this; },
    cross(v) { return this.x * v.y - this.y * v.x; },
    scale(s) {  this.x *= s; this.y *= s; return this; },
});

const Light = {
    pos: V2(),
    Update() {
        if (resized) {
            resized = false;
            this.pos.x = W * 0.5;
            this.pos.y = H * 0.5;
            this.grd = ctx.createRadialGradient(this.pos.x, this.pos.y, 10, this.pos.x, this.pos.y, 1000);
            this.grd.addColorStop(0, "#FFF");
            this.grd.addColorStop(0.01, "#BA4");
            this.grd.addColorStop(1, "#220");
        }
    },
    Draw() {
        ctx.fillStyle = this.grd;
        ctx.fillRect(0, 0, W, H);
    },
};

const Shape = {
    pos: V2(),
    col: "#034",
    sCol: "#8BD",
    verts: [],
    tVerts: [], // transformed
    leftVertIdx: -1,  // -1 for unknown
    rightVertIdx: -1, // -1 for unknown
    Clear() {
        this.verts.length = 0;
        this.tVerts.length = 0;
        this.leftVertIdx = -1;
        this.rightVertIdx = -1;
    },
    Add(...verts) {
        this.verts.push(...verts);
        for (const v of verts) { this.tVerts.push(V2(v.x, v.y)); }
    },
    Update(pos, rot) {  // translate and rotate shape
        i = 0;
        this.pos.set(pos);
        const xAx = Math.cos(rot);
        const xAy = Math.sin(rot);
        for (const v of this.verts) {
            const tV = this.tVerts[i++];
            tV.x = v.x * xAx - v.y * xAy + pos.x;
            tV.y = v.x * xAy + v.y * xAx + pos.y;
        }
    },
    Draw() {
        ctx.fillStyle = this.col;
        ctx.strokeStyle = this.sCol;
        ctx.beginPath();
        for (const tV of this.tVerts) { ctx.lineTo(tV.x, tV.y); }
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    },
    DrawExtrema(from) {
        const wV = V2();
        ctx.fillStyle = "#220";
        ctx.beginPath();
        if (this.leftVertIdx > -1) {
            const tV = this.tVerts[this.leftVertIdx];
            wV.set(tV).sub(from).normalize().scale(10000);
            ctx.moveTo(tV.x + wV.x, tV.y + wV.y);
            ctx.lineTo(tV.x, tV.y);
        }
        if (this.rightVertIdx > -1) {
            let i = (this.leftVertIdx + 1) % this.verts.length;
            while (i != this.rightVertIdx) {
                ctx.lineTo(this.tVerts[i].x, this.tVerts[i].y);
                i = (i + 1) % this.verts.length;
            }
            const tV = this.tVerts[this.rightVertIdx];
            wV.set(tV).sub(from).normalize().scale(10000);
            ctx.lineTo(tV.x, tV.y);
            ctx.lineTo(tV.x + wV.x, tV.y + wV.y);
        }
        ctx.fill();
        ctx.fillStyle = "#000";
     },
     DrawLineToLight(light) {
        ctx.strokeStyle = "#FFF";
        ctx.beginPath();
        if (this.leftVertIdx > -1) {
            ctx.moveTo(light.x, light.y);
            ctx.lineTo(this.tVerts[this.leftVertIdx].x, this.tVerts[this.leftVertIdx].y);
        }
        if (this.rightVertIdx > -1) {
            ctx.moveTo(light.x, light.y);
            ctx.lineTo(this.tVerts[this.rightVertIdx].x, this.tVerts[this.rightVertIdx].y);
        }
        ctx.stroke();
    },
    FindExtrema(from) {
        const left = V2().set(from).sub(this.pos).normalize();
        const right = V2().set(from).sub(this.pos).normalize();
        const wV = V2();
        this.leftVertIdx = -1;
        this.rightVertIdx = -1;
        var i = 0, c;
        for (const tV of this.tVerts) {
            wV.set(tV).sub(from).normalize();
            c = left.cross(wV);
            if (c < 0) {
                this.leftVertIdx = i;
                left.set(wV).neg();
            }
            c = right.cross(wV);
            if (c > 0) {
                this.rightVertIdx = i;
                right.set(wV).neg();
            }
            i++;
        }
    }
};
const RndI = (m) => Math.random() * m | 0;
const Rnd  = (m, M) => Math.random() * (M-m) + m;
function RandomShape() {
   Shape.Clear();
   const vCount = RndI(8) + 4;
   const aStep = TAU / vCount;
   var ang = 0;
   var i = 0;
   while (i < vCount) {
       const a = ang + Rnd(-0.5, 0.5) * aStep;
       const dist = Rnd(50, 100);
       const x = Math.cos(a) * dist;
       const y = Math.sin(a) * dist;
       Shape.Add(V2(x,y));
       ang += aStep;
       i++;
   }
}
Shape.Add(V2(-50, -20), V2(50, -20), V2(50, 20), V2(-50, 20));
requestAnimationFrame(MainLoop);
function MainLoop(time) {
     if (mouse.button) {
        RandomShape();
        mouse.button = false;
     }
     if (canvas.width != innerWidth || canvas.width != innerHeight) { Resize() }
     ctx.clearRect(0, 0, W, H);
     Light.Update();
     Shape.Update(mouse, Math.sin(time * 0.0001) * 0.5);
     Shape.FindExtrema(Light.pos);
     Light.Draw();
     Shape.DrawExtrema(Light.pos);
     Shape.Draw();
     Shape.DrawLineToLight(Light.pos);
     requestAnimationFrame(MainLoop);
}
```

```
canvas { position: absolute; left: 0px; top: 0px; }
div { position: absolute; left: 10px; top: 10px; color: #FFF;}
```

```
<canvas id="canvas" width="10" height="10"></canvas>
<div id="info">Press mouse button to craete random shape</div>
```
> 1 votes

---
Tags: javascript
---