Instantiating Rapidly Causes Objects to Spawn at a Fixed Offset to the Left?

Hi!

I’m asking just in case there is a glaring issue unrelated to specific scripting.

If I try to instantiate anything just once or a few times in a short window it will work fine, but if I instantiate rapidly things, things will begin spawning at a specific offset to the left of where I would like it.

I first noticed it with attempting to Instantiate muzzleFlashes with

GameObject muzzle = Instantiate(muzzleFlash, muzzlePoint.position, muzzlePoint.rotation);

and I made a temporary fix by parenting the muzzle flashes to my muzzle point and setting the transform a second time.

GameObject muzzle = Instantiate(muzzleFlash, muzzlePoint.position, muzzlePoint.rotation);
muzzle.transform.parent = muzzlePoint;
muzzle.transform.position = muzzlePoint.position;

but now I’m stuck facing the same problem when trying to instantiate a hit effect from a raycast with this and I don’t know if there is another easy fix, so I’m hoping to just fix the original problem.

GameObject impactGo = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));

Any help to why I might be having this bug?

Background information: My project was started using FPS Animation Framework (KINEMATION) and I’m using Unity Netcode

Most likely the objects you instantiate have a collider and a non-kinematic rigidbody. Due to them intersecting when they spawn, physics will push them apart to stop them from intersecting.

To stop this, ensure that objects of this kind (projectiles?) do not collide by assigning them a tag (Projectile) and under Project Settings / Physics uncheck the Projectile vs Projectile checkbox in the collision matrix.

1 Like

Thanks for the reply CodeSmile,

Neither of the gameObjects have had colliders or rigidbodies. One held a particle system and the other was a plane representing a bullet decal with a particle system inside :confused:

Are you perhaps moving or animating the muzzlePoint? This could be a one-frame-off issue where you first spawn fx at the muzzle position but then the muzzle moves (ie due to recoil, or simply character movement).

If so, using LateUpdate to spawn the muzzle fx would fix this. Although not entirely for player movement if the fx remains for more than just a few frames but also needs a frame or two before reaching its maximum size. Muzzle flashes are often extremely shortlived for this reason.

2 Likes

Yeah the muzzle point and the camera are subject to animation and movement from parenting objects, I’ll give calling it under LateUpdate a go and see if that solves it. Thanks!

You wouldn’t happen to know if C# offers a method to delay calling a void function or coroutine where it waits for LateUpdate as far as sequencing goes?

C# does offer such delayed execution but it is timed and thus not suitable for a game engine like Unity. Unity itself provides you with coroutines:

IEnumerator WaitUntilEndOfFrame()
{
    yield return new WaitForEndOfFrame();
    // end of frame code here
}

// elsewhere:
StartCoroutine(WaitUntilEndOfFrame());

Thanks for the help! Both using LateUpdate and the WaitUntilEndOfFrame Coroutine solve the issue!

1 Like

WaitForEndOfFrame actually runs after the rendering is completed for this frame. So it’s usually not suitable for game logic and more for post processing after the rendering. Unity also provides the script execution order settings where you can specify the ordering of event methods for certain script types. Unity added the DefaultExecutionOrder attribute which does serve the same purpose, but allows the specify the order in code rather than the project settings.

You shouldn’t overuse or over-rely on this feature. If you need more control over the events or you need some custom events, Unity how has the low level PlayerLoop which allows you to change and modify when and how certain engine features are executed. There’s not a ton of documentation on this but you should find tutorials and examples on the internet.

Don’t get in the habit of using coroutines or ‘delays’ in your code, it turns into a cancer that creates more of the problem you’re using the delay for, making race conditions even more prevalent. There are some genuine issues where you need delays, but they’re very specific and usually UI related - even then it’s probably not even worth adding delays or coroutines for the allocations in some cases.

I remember a while back when I had muzzle flash ‘problems’ like this the issue was that the flash was not parented to the user, so it would spawn and if the character was in motion then as it moved the flash would be left behind. Or, the weapon would have some animation applied to it and not be where it was expected to be. This can be a problem if your muzzle point is not properly attached to your weapon prefab so look into the hierarchy to make sure your flash will spawn and be parented at the correct hierarchy point to get the necessary transformations.

You can also just instantiate one muzzle flash, assign it’s parent, and put a script on it to Flash() instead of creating a new one every time. This would let you design the flash to basically self manage and always be parented as you expect it to be. It’s much more efficient to do it this way.