Trick Shot

TrickShot and TrickShot2D have the same basic setup and functionality 1 for 3D space and 1 for 2D space: TrickShot lets designers compute and visualize a multi‐bounce ballistic trajectory at runtime (storing it in prediction) and then spawn a BallisticPathFollow prefab along that exact path via Shoot(). It’s ideal for “grenade launcher”–style weapons or any projectile that should follow a precomputed arc with optional bounces.
Public Fields
Speed
float speedInitial launch speed (units/sec). Combined withtransform.forwardto form the launch velocity.
Constant Acceleration
Vector3 constantAccelerationGravity or custom acceleration applied throughout flight. Defaults to(0, –9.81f, 0).
Radius
float radiusSphere‐cast radius used when predicting collisions. Set this to roughly match your projectile’s size.
Template
BallisticPathFollow templateA reference to a prefab (or scene object) that hasBallisticPathFollowon it.At
Shoot(), this prefab is instantiated, and itsprojectileandpathfields are filled using the computedprediction.
Resolution
float resolution(minimum0.01) Sampling increment for each prediction segment. Smaller values → finer trajectory at higher CPU cost.
Distance
float distanceMaximum trace length per segment (or total, seedistanceIsTotalLength).
Collision Layers
LayerMask collisionLayersLayers used for collision detection when predicting. Only colliders on these layers will register impacts.
Trigger Interaction
QueryTriggerInteraction triggerInteractionWhether to include triggers in collision checks (UseGlobal,Ignore, orCollide).
Bounces
int bouncesNumber of allowed bounces after the first impact. Set to 0 for a single arc, >0 to simulate up to N bounces.
Bounce Damping
float bounceDamping([0, 1]) Fraction of velocity lost on each bounce. A value of 0.5 means the reflected velocity is halved after impact.
Distance Is Total Length
bool distanceIsTotalLengthfalse(default) – Each segment’sPredict()usesdistanceas its own distance limit.true– After each bounce, subtract that segment’sflightDistancefromdistance, sodistancebecomes the maximum total arc length across all segments.
Prediciton
List<BallisticPath> predictionThe computed list ofBallisticPathsegments. After callingPredict(), this list holds one entry per segment (first arc plus each bounce arc). Designers can inspect or draw these paths before spawning.
Public Methods
Predict
void Predict()
Compute and store a full, multi‐bounce trajectory in prediction.
Workflow
Creates a local
BallisticsDatawith:velocity = transform.forward * speedradiusas assigned.
Clears any previous contents of
prediction.If
bounces == 0, simply does oneproj.Predict(...)from the current position:csharpCopyEditprediction.Add( projectileSettings.Predict( selfTransform.position, null, resolution, distance, collisionLayers, triggerInteraction, constantAcceleration ) );If
bounces > 0, runs a loop up tobouncestimes:Calls
proj.Predict(...)from the current launch point (pos) with the currentproj.velocityand either:distance(ifdistanceIsTotalLength == false), orthe remaining distance (if
distanceIsTotalLength == true).
Adds the returned
BallisticPathtoprediction.If there’s no impact, breaks out (no further bounces).
Otherwise, reflects the last‐step velocity against the impact normal and multiplies by
(1 – bounceDamping), then uses that as the newproj.velocityfor the next segment.If
distanceIsTotalLength == true, subtracts the just‐used segment’sflightDistancefrom remaining distance.
Designer Usage
Call
Predict()whenever you want to update the visible trajectory (e.g., on aim adjustment or when parameters change).After
Predict(), inspectprediction(for example, draw gizmos from eachBallisticPath.steps[i].position) or feed it directly into aLineRenderer/debug draw.
Shoot
void Shoot()
Instantiate the BallisticPathFollow prefab and assign the precomputed trajectory so the spawned object moves exactly along it.
Workflow
Instantiates a copy of
template.gameObjectattransform.position/transform.rotation.Retrieves its
BallisticPathFollowcomponent (comp).Creates a new
BallisticsDatainsidecompwith:velocity = transform.forward * speedradiusas configured.
Assigns
comp.pathto a newList<BallisticPath>(prediction)(makes a copy).If
predictionis empty, logs a warning: “No prediction path available, projectile spawned but may not behave as expected.”
Designer Usage
After calling
Predict(), simply callShoot(). The newly spawned object will begin its path in its nextLateUpdatecall.You do not need to manually set
comp.projectileorcomp.path—Shoot()handles it.
Typical Designer Workflow
Scene Setup
Place a GameObject in the scene (e.g., a “Launcher”) and attach:
TrickShotAny aiming/rotation scripts you want (e.g., rotating to face a target).
Assign a
BallisticPathFollowprefab astemplateonTrickShot. Ensure that prefab has aBallisticPathFollowcomponent and is configured (layer masks, events, etc.).
Configure Parameters in Inspector
speed: E.g.,25ffor a medium‐range launch.constantAcceleration: Leave at(0, –9.81f, 0)for earth‐like gravity.radius: E.g.,0.1ffor a small projectile.resolution: E.g.,0.02ffor a smooth curve.distance: E.g.,50fto trace up to 50 units.collisionLayers: Tick “Environment” or “Obstacles.”bounces: E.g.,1if you want exactly one bounce.bounceDamping: E.g.,0.3fto lose 30% speed on each bounce.distanceIsTotalLength: Enable if you want the sum of all segments capped atdistance(otherwise each segment is capped individually).
Call
Predict()In a custom aiming script or UI (e.g., when the player adjusts aim), call:
csharpCopyEditGetComponent<TrickShot>().Predict();Use
predictionto draw a debug arc or aLineRendererso the player sees the full flight + bounce.
Call
Shoot()When the player fires, simply call:
csharpCopyEditGetComponent<TrickShot>().Shoot();A new object (from your
BallisticPathFollowtemplate) spawns attransform.positionand immediately begins moving along the precomputedpath.
Designer Tips & Gotchas
Ensure
predictionIs Up to Date Always callPredict()right beforeShoot()(or enablePredict()in an “OnAimChanged” event). If you forget,Shoot()will warn thatpredictionis empty, and the projectile might not travel correctly.Matching Radius & Collider Use the same
radiusin bothTrickShotand theBallisticPathFollow’sprojectileso that collisions align perfectly during prediction and actual flight.Distance Logic
If
distanceIsTotalLength == false, each segment can travel up todistancebefore ending—even if the first bounce happened early.If
true, the sum of all segments’flightDistancecannot exceeddistance, ensuring a hard cap on total arc length.
Multiple Bounces Set
bouncesto the maximum number of bounces you expect. If the path never actually collides before reachingdistance, the loop breaks early.Performance Consideration A small
resolution(e.g.,0.005f) plus many bounces can generate hundreds of samples—use a slightly larger value (e.g.,0.02f–0.05f) unless you need extreme precision.Custom Gravity If you want no gravity, set
constantAcceleration = Vector3.zero. For unusual physics fields (e.g., a planet with weak gravity), adjust accordingly.
Last updated