hey guys , So as you can see i made a robot arm grab a slingshot's objectholder with a ball in it. My arm pulls it any direction I want it but I wanted the user to know which box is going to be shot at. So i thought how about i make a trajectory Predictor on the ball so it shows where the ball is going. I wanted to know how should I start this or is there anything easier to make this goal. And yes i am doing research and trying stuff. I just want to get more advice or help. Please and thank you :)
CodePudding user response:
If you're applying an impulse force (or velocity) to your ball and there is gravity in your world, your item will follow the Projectile motion;
Here you can find details about it:
and would need slightly rework from 2D to 3D physics, should be trivial though since the important part about the Y axis basically stays the same.
You would
- Call this simulation with according supposed shoot direction and velocity
- Visualize the tracked positions e.g. in a
LineRenderer
Physics.Simulate
This allows you to run physics updates manually all within a single frame and actually let the Physics engine handle it all for you
This costs of course a lot of performance but you get all collisions etc accounted for automatically without getting a headache
You would
- Make a snapshot of all Rigid bodies in your scene - in order to reset after the simulation
- Simulate the desired amount of physics steps (XY seconds ahead) while keeping track of the simulated data
- reset everything to the state tracked in step 1
- use the simulated data from step 2 to visualize e.g. with a
LineRenderer
This might look somewhat like e.g.
public class Prediction : MonoBehaviour
{
public LineRenderer line;
public Rigidbody tracked;
private Rigidbody[] allRigidbodies;
private void Awake()
{
allRigidbodies = FindObjectsOfType<Rigidbody>();
}
private void LateUpdate()
{
// Wherever you would get this from
Vector3 wouldApplyForce;
// Step 1 - snapshot
// For simplicity reasons for now just the positions
// using some Linq magic
var originalPositions = allRigidbodies.ToDictionary(item => item, item => item.position);
// Step 2 - Simulate e.g. 2 seconds ahead
var trackedPositions = new Vector3 [(int) (2 / Time.fixedDeltaTime)];
Physics.autoSimulation = false;
tracked.AddForce(wouldApplyForce);
for(var i = 0; i < trackedPositions.Length; i )
{
Physics.Simulate(Time.fixedDeltaTime);
trackedPositions[i] = tracked.position;
}
// Step 3 - reset
foreach (var kvp in originalPositions)
{
kvp.Key.position = kvp.Value;
}
Physics.autoSimulate = true;
// Step 4 - Visualize
line.positionCount = trackedPositions.Length;
line.SetPositions(trackedPositions);
}
}
Of course we won't talk about performance here ^^