Skip to content

Slingshot

namespace Griff.Modules.PhysicsGames;
public sealed class Slingshot : Component, IDrawable, IPlaytestReport, IActionReady

A slingshot that launches things into a physics game, with no code: pull its pouch back with the mouse (or a finger) and let go, and the shot in it flies off the other way, the faster the further it was pulled. Its shots are the bodies inside it, waiting their turn in a row behind it (birds, boulders, crates), and then copies of its Shot prefab, Shots of them. While it’s pulled a dotted line shows where the shot will go, and the camera follows the shot as it flies.

With the keys or a gamepad, the arrows (A, D, W, S, the d-pad or the stick) pull the pouch about and the LaunchAction (Space, A) lets go; the CancelAction (Shift, B) lets it back. It loads its next shot by itself LoadDelay seconds after each shot comes to rest (or on its Load action), and its Launch action launches what’s loaded at its DefaultPull with nobody pulling it: a catapult a Trigger, a wire or a script fires. Its ShotsLeft output counts what it has left to launch, and OutOfShots turns on once the last has come to rest. Give it a TurnTaker and it’s pulled only on its side’s turn, each launch using one of the turn taker’s actions; untick Controllable (or Focus something else) and it ignores the mouse and keys.

This is a component: its saved properties are on its component page.

public bool AutoLoad { get; set; }

Loads its next shot by itself, LoadDelay seconds after the last has come to rest (and its first as the game starts); untick it to load on its Load action.

public Color BandColor { get; set; }

The color of its elastic bands.

public bool CameraFollows { get; set; }

The camera follows each shot as it flies, and goes back to what it followed once the shot has come to rest (or the next is loaded). Needs a Follow on the camera: a slingshot made from the Entity menu gives it one following the slingshot.

public string? CancelAction { get; set; }

The input action that lets the pouch back without launching: “Dash” is Shift or the gamepad’s B.

public Color Color { get; set; }

The color of its frame.

public bool Controllable { get; set; }

Untick it to have it ignore the mouse, keys and gamepad (its actions and scripts still work): another part of the scene has the player’s input. Its Focus action ticks it and unticks it on everything else the player plays.

public Vector2 DefaultPull { get; set; }

How far its pouch is pulled (in the world) when its Launch action launches with nobody pulling it: (-2, -1) launches up and to the right at full power.

public string? Flying { get; set; }

The shot it last launched, by its entity’s id, while it’s flying: what the camera follows. Set by the game.

public float FlyingFor { get; set; }

Seconds the shot it last launched has been flying. Set by the game.

public float FlyingStill { get; set; }

Seconds the shot it last launched has been all but still. Set by the game.

public float ForkWidth { get; set; }

How far apart the two prongs of its fork are, in world units.

public float GrabRadius { get; set; }

How near its pouch (in world units) a press of the mouse or a finger takes hold of it.

public string? LaunchAction { get; set; }

The input action that lets go of the pouch pulled with the keys: “Jump” is Space or the gamepad’s A.

public string? LaunchMessage { get; set; }

A message sent with Game.Send as a shot is launched, with the shot as its data, e.g. “Launched”.

public string? LaunchSound { get; set; }

A sound played as a shot is launched, e.g. “Sounds/twang.wav”.

public float LoadDelay { get; set; }

Seconds after its last shot has come to rest (or gone) that it loads its next (with AutoLoad).

public float LoadIn { get; set; }

Seconds until it loads its next shot by itself; 0 when it isn’t waiting to. Set by the game.

public bool Loaded { get; set; }

True while a shot sits in its pouch: its first shot inside it. Set by the game.

public Entity? LoadedShot { get; }

The shot in its pouch while it’s Loaded, or null.

public int Made { get; set; }

How many copies of its Shot prefab it has made so far. Set by the game.

public float MaxPull { get; set; }

How far its pouch can be pulled back from where it rests, in world units: the circle round its pouch in the Scene view.

public float MinPull { get; set; }

Pulled less far than this, it’s let back without launching.

public bool OutOfShots { get; set; }

True once it has no shots left (none inside it, none of its prefab) and the last it launched has come to rest or gone: wire it to a panel that says the level’s lost. Set by the game.

public string? OutOfShotsMessage { get; set; }

A message sent once it has no shots left and its last has come to rest, e.g. “OutOfShots”: time to lose.

public Vector2 Pouch { get; set; }

Where a loaded shot rests, from its position (its foot): in the fork at its top.

public Vector2 PouchInWorld { get; }

Where a loaded shot rests in the world: its Pouch.

public float Power { get; set; }

How fast a shot leaves it when pulled all the way back, in world units a second; less the less it’s pulled.

public float Preview { get; set; }

Seconds of a shot’s flight the dotted line shows while it’s pulled; 0 shows none.

public Color PreviewColor { get; set; }

The color of the dots showing where a shot will go.

public Vector2 Pull { get; set; }

How far its pouch is pulled from where it rests, in the world, right now. Set by the game as it’s pulled.

public float PullSpeed { get; set; }

How fast the keys and a gamepad pull its pouch about, in world units a second.

public string? Shot { get; set; }

A prefab it loads a copy of once the shots inside it have gone, e.g. “Bird”: up to Shots of them. Empty launches only the bodies inside it.

public int Shots { get; set; }

How many copies of its Shot prefab it has to launch, after the shots inside it.

public int ShotsLeft { get; }

How many shots it has left to launch: those inside it (the loaded one too) and the copies of its prefab still to come.

public float Stretch { get; }

How far it’s pulled, from 0 (resting) to 1 (all the way back).

public string? StretchSound { get; set; }

A sound played as its pouch is first pulled back.

public void Launch()

Launches the shot in its pouch as it’s pulled, or at its Default Pull with nobody pulling it (a catapult a trigger fires).

public Vector2 LaunchVelocity(Vector2 pull)

How fast a shot pulled back pull (in the world) leaves it: the other way, at its Power times how far that is of its MaxPull.

public void Load()

Loads its next shot into its pouch now, if it has none loaded and has one left.

public override bool Uses(string property)
public event Action<Slingshot, Entity>? Launched

Raised as it launches a shot, with the shot.