# Question 2D physics simulation to create trajectory prediction

Discussion in 'Physics' started by ahcollin, Apr 22, 2022.

1. ### ahcollin

Joined:
Jan 12, 2016
Posts:
7
I have a 2D brick breaker style game in Unity where you get to choose the angle of your shot before each turn with the mouse. I'd like to show an accurate trajectory prediction of what a ball will do while the player is aiming, up to maybe 200 frames of ball movement. This involves potentially bouncing off the top, left, and right walls, and any bricks.

I'm using a physics simulation and line renderer to accomplish this but can't get it to work correctly.

It's supposed to copy the gun, walls, and bricks into a virtual Scene, launch a ball in the angle the player is aiming, simulate 200 frames of movement, and plot those in a line renderer.

Here is an abridged version of the game code, reduced to just focus on the aiming and physics simulation for the 1st turn. When I run it, it simply plots the 200 points of the line renderer in the same coordinates as the gun.

Any help is appreciated, thank you.
Code (CSharp):
1.
2. using UnityEngine;
3. using UnityEngine.SceneManagement;
4.
5. public class Aim3 : MonoBehaviour
6. {
7.
8.     private Vector3 gunPosScreenV3, aimPointScreenV3,
9.         aimPointWorldV3, aimDirectionV3;
10.
11.     private Vector2 ballDirection, ballVelocity;
12.
13.     [SerializeField] private GameObject gun, walls, bricks;
14.
15.     Camera cam;
16.     LineRenderer lr;
17.
18.     // For Physics Scene
19.     private int maxPhysicsFrameIterations = 200;
20.     private Scene simulationScene;
21.     private PhysicsScene2D physicsScene;
22.     [SerializeField] private GameObject ballPrefab;
23.     private GameObject ghostObj;
24.
25.     void Start()
26.     {
27.         lr = GetComponent<LineRenderer>();
28.         lr.enabled = true;
29.         cam = Camera.main;
30.         CreatePhysicsScene();
31.     }
32.
33.     void Update()
34.     {
35.         DrawTrajectory();
36.     }
37.
38.     // This is run once to create a duplicate of the game board for the physics simulation
39.     private void CreatePhysicsScene()
40.     {
41.         simulationScene = SceneManager.CreateScene("Simulation", new CreateSceneParameters(LocalPhysicsMode.Physics2D));
42.         physicsScene = simulationScene.GetPhysicsScene2D();
43.
44.         // Copy the gun to the simulated scene
45.         ghostObj = Instantiate(gun.gameObject, gun.transform.position, gun.transform.rotation);
46.         ghostObj.GetComponent<SpriteRenderer>().enabled = false;
47.         SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
48.
49.         // Copy all the bricks to the simulated scene. These are stored under a parent Game Object that
50.         // is attached in the editor
51.         foreach (Transform obj in bricks.transform)
52.         {
53.             ghostObj = Instantiate(obj.gameObject, obj.position, obj.rotation);
54.             ghostObj.GetComponent<SpriteRenderer>().enabled = false;
55.             SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
56.         }
57.
58.         // Copy the top, left, and right walls to the simulated scene. These are invisible and don't have sprites.
59.         // These are stored under a parent Game Object that is attached in the editor
60.         foreach (Transform obj in walls.transform)
61.         {
62.             ghostObj = Instantiate(obj.gameObject, obj.position, obj.rotation);
63.             SceneManager.MoveGameObjectToScene(ghostObj, simulationScene);
64.         }
65.     } // CreatePhysicsScene
66.
67.     private void DrawTrajectory()
68.     {
69.         // Get the starting Screen position of the gun from the World position
70.         gunPosScreenV3 = cam.WorldToScreenPoint(gun.transform.position);
71.         gunPosScreenV3.z = 1;
72.
73.         // Get position of mouse in screen units
74.         aimPointScreenV3 = Input.mousePosition;
75.
76.         // Get the position of the mouse in world units for aiming
77.         aimPointWorldV3 = cam.ScreenToWorldPoint(aimPointScreenV3);
78.         aimPointWorldV3.z = 1;
79.
80.         // Calculate the normalized direction of the aim point compared to the gun
81.         aimDirectionV3 = (aimPointScreenV3 - gunPosScreenV3).normalized;
82.
83.         Physics2D.simulationMode = SimulationMode2D.Script;
84.
85.         // Instantiate the ball prefab for the simulation
86.         ghostObj = Instantiate(ballPrefab, gun.transform.position, Quaternion.identity);
87.
88.         // Assign the ball's velocity
89.         ballDirection = new Vector2(aimDirectionV3.x, aimDirectionV3.y);
90.         ballVelocity = ballDirection * 20f;
91.         ghostObj.GetComponent<Rigidbody2D>().velocity = ballVelocity;
92.         SceneManager.MoveGameObjectToScene(ghostObj.gameObject, simulationScene);
93.
94.         lr.positionCount = maxPhysicsFrameIterations;
95.
96.         for (var i = 0; i < maxPhysicsFrameIterations; i++)
97.         {
98.             physicsScene.Simulate(Time.fixedDeltaTime);
99.             //Physics2D.Simulate(Time.fixedDeltaTime);
100.             lr.SetPosition(i, ghostObj.transform.position);
101.         }
102.
103.         Destroy(ghostObj);
104.
105.         Physics2D.simulationMode = SimulationMode2D.Update;
106.
107.     } // DrawTrajectory
108.
109. }

2. ### arfish

Joined:
Jan 28, 2017
Posts:
780
How about making prediction shoots with some kind of objects with the sama physics properties as the "real" bullets, that leaves a trail plotting the trajectory? But that is maybe what you already are trying to do when "using a physics simulation and line render"?

### Unity Technologies

Joined:
May 24, 2013
Posts:
11,101
You said a lot of words and posted a lot of code but never actually said what was wrong! Apart from "it simply plots the 200 points of the line renderer in the same coordinates as the gun" but is that supposed to be the problem? I have no idea what that means. What are you expectations and what is it doing. For this, I believe an image would help because ... what is the "gun" and what should it look like?

You should spend more time describing the problem and less so your solution.

4. ### ahcollin

Joined:
Jan 12, 2016
Posts:
7
Oops

I meant the physics simulation didn't work. It's supposed to launch the ball and simulate the physics of it. But it didn't launch, the ball simply stayed in the same place.

Regardless, it's now fixed. The velocity needed to be added to the ball after moving it to the simulated scene, not before.

MelvMay likes this.

### Unity Technologies

Joined:
May 24, 2013
Posts:
11,101
Yes, body velocity is a volatile property not part of the serialized state, same as angular velocity.