Mar
19
2013

Fast Projectiles

fast_projectiles_unity3d

Testing a script for fast moving projectiles (since normal physic objects always go through walls..)

Current version info:
– No colliders, rigidbodies or raycasts for the projectile
– Just move the objects inside FixedUpdate()
– Projectile gets the target point when clicked, it doesnt check collisions while flying..

There is also this, havent tested it yet: DontGoThroughThings
http://wiki.unity3d.com/index.php?title=DontGoThroughThings

Also physics settings could be adjusted:
http://docs.unity3d.com/Manual/class-PhysicsManager.html

See comments for more solutions..

Webplayer:
http://unitycoder.com/upload/demos/FastProjectiles/

Download source: (unity 4.1)
FastProjectiles.unityPackage (c#)

Here’s also modified test version of  the unitywiki “DontGoThroughThings.js”
– Do a raycast from the previous position to the current position
– Then if raycast hits something, just stop (could set velocity to zero etc..)

#pragma strict
public var layerMask : LayerMask;
private var previousPosition : Vector3;
private var currentPositionRayTo : Vector3;
private var myRigidbody : Rigidbody;
private var hit : RaycastHit;

function Awake() {
myRigidbody = rigidbody;
previousPosition = myRigidbody.position;
}

//function FixedUpdate()
//function OnGUI()
function Update()
{
currentPositionRayTo = (transform.position-previousPosition);
//    Debug.DrawRay(transform.position, currentPositionRay, Color.green);
if (Physics.Raycast(previousPosition, currentPositionRayTo, hit, Vector3.Distance(transform.position, previousPosition), layerMask.value))
{
// we hit something, do stuff here (for example stop the force/speed/velocity, otherwise we would keep moving..)
//constantForce.enabled = false;
myRigidbody.position = hit.point;
}
previousPosition = myRigidbody.position;
}


15 Comments + Add Comment

  • Hi!,

    First of all I would like to thank you for sharing all this ideas.

    I have checked the wiki entry and it is the way I do this now. Would you mind commenting your method to do not use Raycasting? The other thing I would like to comment is that I do not understand why there is a need to do this all in FixedStep. At least for the wiki example. The FixedStep function will be called more times than Update method but in the wiki code it is raycasting from previous to current position, so why not to wait and do this once in the next Update?

    Thanks in advance.

    • Added the current source download.

      Not sure why DontGoThroughThings needs FixedUpdate(), tried with Update() also and it seems to miss the plane at some speeds where FixedUpdate() gets it.. made simplified test version of it, just do raycast from previous pos to current, if hit something then stop. Seems to work ok in few tests..

    • DontGoThroughThings needs FixedUpdate() because it is working with Rigidbodys and Colliders and ONLY performs the raycasts if the movement of the rigidbody between two physics frames was great enough to surpass the attached Colliders extents.

      In every other case the normal collision detection of the Physics engine is enough. If you would put it into Update() i guess it could give some false positives if the frame rate is low – or wouldnt trigger at all if it is to high (>50) because the movement between 2 frames is never more than its extents

      However, i found it worked rather strange since the passing will happen anyway but one frame later the object is teleported back to the old position…. very bad if you use trailrenderers to smooth the projectiles apperance (the trail will go through the wall and then back to the raycast hitpoint). Therefore i modified it in my first implementations by forecasting to the next position if the velocity is great enough. Then it wont pass the wall and immediately is ported to the point (which is also bad because the teleport gives the projectile a velocity leap before it hits the wall)

      check my current solution below, it is way better but without colliders (=projectiles have no width)

  • I also tinkered around with fast projectiles. What i ended up with is a kind of Raycast-interval.
    it’s working great, only catch was that hitable objects moving against the projectile are prone to be missed (because: http://forum.unity3d.com/threads/134650-Rigidbody-Bullets)
    so i use raycasts and additionally check if the position of the bullet is within a moving hitable object to counter that.

    i sticked with FixedUpdate() for the framerate independence of the hit detection, it should be moveable to Update(). The Rigidbody is just a left over and can be converted to manual movement instead of velocity setting

    so there are only a few cases where i occasionally fail to detect a hit:
    -if the hitable object moves so fast that its discrete positions in fixed update don’t overlap (my game doesn’t allow that)
    -if the object approaches the projectile in orthogonal direction (can be fixed with continous “contains” checks instead of conditional)

    the script is somewhere in this project file:
    http://forum.unity3d.com/threads/124019-SpaceNox-Working-Title/page3?p=1186317&viewfull=1#post1186317

    “RaycastDestruction.cs” if i remember it right, but its overloaded with other stuff that allows projectiles to seek targets, bounce of walls and get slowed down by dampening fields

  • Nice, arrows. I’ve been collecting projectiles, now I have 2 I like,

    yours and this one

    https://sites.google.com/site/terrymorgan1213/tutorials/ali-looqman-blaster

    wondering if there’s a new/better/another way to switch weapons than in the Unity 3d FPS
    tutorial from 2009.

    https://sites.google.com/site/terrymorgan1213/tutorials/fps-tutorial-rocket-launcher

  • I found your blog late last night and it has completely re-inspired me to continue working in/on Unity. I hope you don’t mind me stealing all of your source! XD

    • thanks! no problems and feel free to post improvements/interesting links 🙂

  • physics trick switching between collision modes:
    http://forum.unity3d.com/threads/187105-Handy-Physics-Trick

  • Great article 😉
    Here is my contribution.

    Projectile to always hit a moving object: http://lexiconhub.tk/index/game-programming/projectile-motion-unity-3d/

    Hope this helps 🙂
    Thanks

  • Unity realistic bullet ballistics (with example sources)


  • Has anyone tried fast projectiles with Unity5?

    “Collision detection

    Continuous collision detection has been improved by an order of magnitude. Continuous collision detection is used to prevent fast-moving bodies from going through other bodies without any collisions detected. Imagine a bullet shot at a piece of paper, or a game of pool where some balls will move faster than others.

    In Unity 5.0, the SDK generates all the data required to handle fast movement. You just enable continuous collision detection and it works. PhysX3 features an algorithm used to detect whether the expensive CCD simulation is actually needed given the current body velocity or a default discreet would do just fine. It’s activated once you enable the CCD.”

    http://blogs.unity3d.com/2014/07/08/high-performance-physics-in-unity-5/

    • Hi mgear, has been some time since i did smth in Unity… i’m still chewing on serumas script every once in a while…

      However, i tried the Unity5 Collision detection and this is what i got:

      Shooting the target from front in line within its move direction:
      Barrel = – – – – Target

      -Discrete on Bullet(Fast) misses the Target(Slow) in any case
      -ContinuousBullet misses the Target if the target is not DynamicContinuous
      -DynamicContinousBullet hits the Target always, even if the target is moving very fast (more than its extents/frame)

      So Unity5 is totally capable of handling these now

      But when i shoot a target moving sideways fast it seems that Unity cannot detect collisions that would happen in between ph.frames if the moving directions are orthogonal to each other. But i have to make a better testsetup for this case.

      small sketch, these bullets should hit, but don’t
      o Bullet 1 pos1
      |
      |
      o Bullet 1 pos2
      <_| _o _ _o Bullet 2 pos1
      |
      o Bullet 1 pos3
      |
      |
      V

  • Could you re-upload the source somewhere? I would like to take a look at your technique, even if it won’t work in the latest version of Unity, but the link to download has ‘expired’.

Leave a comment

Connect

Twitter View LinkedIn profile Youtube Youtube Join Discord Twitch

UnityLauncherPro

Get UnityLauncherPRO and work faster with Unity Projects!
*free unity hub alternative

@unitycoder_com

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.