How can I use mpu6050 and arduino uno to control cube so the cube will move with mouse position? - unity3d

When I first tried the arduino code with my mpu6050, the serial monitor showed the readings. However, when I tried to connect it with unity, the readings cannot be showed or used in unity. I was stuck at this problem. I was trying to make the cube that i created in unity to move with the mouseposition then replaced by the mpu 6050.
Arduino code
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz;
int vx, vy;
void setup() {
Serial.begin(115200);
Wire.begin();
mpu.initialize();
//if (!mpu.testConnection()) { while (1); }
}
void loop() {
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
vx = ((gx+300)/150)-1; // "+300" because the x axis of gyroscope give
values about -350 while it's not moving. Change this value if you get
something different using the TEST code, chacking if there are values far
from zero.
vy = -(gz-100)/150; // same here about "-100"
String output = String(gx) + ";" + String(gz) + ";" + String(vx) + ";" +
String(vy);
Serial.println(output);
Serial.flush();
delay(10);
}
Unity code
public class Cube : MonoBehaviour {
SerialPort stream = new SerialPort("COM4", 115200);
public Camera cam;
public float mousex;
public float mousey;
public GameObject target; // is the gameobject to
public float acc_normalizer_factor = 0.00025f;
public float gyro_normalizer_factor = 1.0f / 32768.0f; // 32768 is max
value captured during test on imu
//float curr_angle_x = 0;
//float curr_angle_y = 0;
//float curr_angle_z = 0;
float curr_offset_x = 0;
float curr_offset_y = -2;
void Start()
{
stream.Open();
cam = Camera.main;
}
void Update()
{
string dataString = "null received";
dataString = stream.ReadLine();
char splitChar = ';';
string[] dataRaw = dataString.Split(splitChar);
float vx = int.Parse(dataRaw[2]);
float vy = int.Parse(dataRaw[3]);
curr_offset_x += (vx * acc_normalizer_factor);
curr_offset_y += (vy * acc_normalizer_factor);
//get mouse possition
mousex = (curr_offset_x);
mousey = (curr_offset_y);
//adapt it to screen
// 5 in z to be in the front of the camera, but up to you, just
avoid 0
Vector3 mouseposition = cam.ScreenToWorldPoint(new Vector3(mousex,
mousey, 5));
//make your gameobject fallow your input
target.transform.position = mouseposition;
}

First of all, check your device. Is the data being sent by your device and received by machine the mpu is connected to?
Also you can try to Debug.Log(dataString) in Unity right after dataString = stream.ReadLine(); in your code (it makes sense only if data from mpu is receiving by machine your device is connected to).

Related

Problem rotating an object on its local orientation

Hello i am new in the forum! I hope i am in the right section! Im trying to rotate a camera (that rapresent the player POV) using the mouse delta and im rotating the camera in local coordinates not world coordinates and i want avoid gimbal lock effect. I read somewhere on the internet that for that purpose i have to use quaternions, and i read how to do that. The problem is that axis rotations works well moving in local orientation but one of the axis is losing its local orientation and it rotate following the world coordinates orientation. I will post the code and i hope someone can help me and telling me where im doing things wrong. Thanks!
public class Player : MonoBehaviour {
[Header("Camera")]
[SerializeField] private Camera _camera;
[SerializeField] private Vector2 _xMinMaxRotation = new Vector2(-90, 90);
[SerializeField] private Vector2 _yMinMaxRotation = new Vector2(-90, 90);
[SerializeField] private float _mouseXSensistivity = 1;
[SerializeField] private float _mouseYSensistivity = 1;
[SerializeField] private float _mouseZSensistivity = 1;
[SerializeField] private float _xStartRotation = 0;
[SerializeField] private float _yStartRotation = 0;
private Vector2 _mouseDelta;
private float _rotY, _rotX, _rotZ;
//public GameObject head;
// Start is called before the first frame update
void Start() {
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update() {
_mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
MoveCamera();
}
private void MoveCamera() {
_rotX += _mouseDelta.x * _mouseXSensistivity * Time.deltaTime * 100;
_rotX = Mathf.Clamp(_rotX, _xMinMaxRotation.x, _xMinMaxRotation.y);
_rotY += _mouseDelta.y * _mouseYSensistivity * Time.deltaTime * 100;
_rotY = Mathf.Clamp(_rotY, _yMinMaxRotation.x, _yMinMaxRotation.y);
//Calculation for RotZ
if (Input.GetKey(KeyCode.Q)) {
_rotZ += +_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ > 25) _rotZ = 25;
}
else {
if (_rotZ > 0) {
_rotZ -= 2 * _mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ < 0) _rotZ = 0;
}
}
if (Input.GetKey(KeyCode.E)) {
_rotZ += -_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ < -25) _rotZ = -25;
}
else {
if (_rotZ < 0) {
_rotZ -= 2 * -_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ > 0) _rotZ = 0;
}
}
Quaternion currentRotation = Quaternion.identity;
currentRotation = currentRotation * Quaternion.AngleAxis(_rotX, transform.up);
currentRotation = currentRotation * Quaternion.AngleAxis(-_rotY, transform.right);
currentRotation = currentRotation * Quaternion.AngleAxis(_rotZ, transform.forward);
_camera.transform.localRotation = currentRotation;
//head.transform.position = _camera.transform.position;
//head.transform.rotation = _camera.transform.rotation;
}
The last part with quaternions is where im trying to calculate angles in order to properly rotate in local coordinates.
You don’t need to use quaternions at all.
You can use transform.EulerAngles instead of the transform.rotation or transform.localEulerAngles instead of transform.LocalRotation.
I messed up the capitalization I’m sure.
Say you wanted to rotate the camera 10 degrees along the local x axis. That would look something like
transform.localEulerAngles = transform.localEulerAngles.Add(10,0,0);
That’s it as far as I know. If you wanna read more about this,
transfrom.localEulerAngles
If your question was completely different, let me know and I can change or remove my answer.

The jumping and movement code for my player only works intermittently

So I am developing an online multiplayer FPS game for my SDD major work, and I have run into a problem. Below is the movement code for my player. I am trying to implement strafing and bunnyhopping into my game, and so I setup a test environment within my project and I managed to get everything working. The only problem was that after I tried to put this back into my main project, it stopped working.
The main problem is that the jumping only works sometimes. The player only jumps a very small amount, and sometimes stay there, meaning that there is no friction as the player is stuck off the ground. He also seems to phase beneath the ground a tiny bit, but the collider on him shouldn't let that happen. I have tried to remove the code that makes downward falls faster, but that only fixes it sometimes.
Code link: https://pastebin.com/cLkemQhX
public class PlayerMovement: MonoBehaviourPun
{
[Header("Movement Settings")]
public float maxVelocityGround = 15f;
public float maxVelocityAir = 10f;
public float groundAccelerate = 90f;
public float airAccelerate = 180f;
public float fallMultiplier = 1.2f;
public float lookSens = 8f;
public float slowDrag = 0;
public float thrusterForce = 7f;
public float friction = 10f;
private float _friction = 0f;
[Header("Rotation")]
float xRot = 0F;
float yRot = 0F;
float minY = -90f;
float maxY = 90f;
Quaternion originalRotation;
//More Movement Variables
private float distToGround;
private Vector3 _velocity;
private Vector2 xyVelocity;
[Header("References")]
//public Text grounded;
//public Text velocity;
public Camera cam;
private Move motor;
private Rigidbody rb;
private CapsuleCollider collidr;
private GameObject rayPoint;
//private PlayerSetup playerSetup;
//Booleans
private bool jumpy = false;
void Start()
{
_friction = friction;
//Locks the cursor to the middle of the screen, and hides it from view
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
//These attatch the correct objectss to their references in the script, defined above
motor = GetComponent<Move>();
rb = GetComponent<Rigidbody>();
collidr = GetComponent<CapsuleCollider>();
rayPoint = GameObject.Find("point");
//playerSetup = GetComponent<PlayerSetup>();
//Sets the distance to the ground from the center of the collider, used in determining whe nthe player is on the ground
distToGround = collidr.bounds.extents.y;
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
originalRotation = transform.localRotation;
}
void FixedUpdate()
{
//Debug function that shows a visual representation of when the player is on the ground
//string a = isGrounded().ToString();
//grounded.GetComponent<Text>().text = a;
//Finds the Velocity in the x plane. Also used in debug, as it shows it on screen
//xyVelocity = new Vector2(rb.velocity.x, rb.velocity.z);
//velocity.GetComponent<Text>().text = xyVelocity.magnitude.ToString("0.000");
//This statement checks if the player both is on the ground, and has requested to jump. If so it will jump
//while also not allowing multiple jumps while in the air. If the player holds it down, he will jump as soon
//as he touches the ground, avoiding friction and allowing the player to bunnyhop
if (Input.GetKey("space") && isGrounded())
{
rb.AddForce(Vector3.up * thrusterForce, ForceMode.Impulse);
jumpy = true;
}
//rb.AddForce(Jump(), ForceMode.Impulse);
//This makes you fall faster than you rise, and make jumping feel nicer overall.
if (rb.velocity.y < 0)
{
rb.velocity += Vector3.up * Physics.gravity.y * fallMultiplier * Time.deltaTime;
}
//Gets the input from the axis'
float input_y = Input.GetAxis("Vertical");
float input_x = Input.GetAxis("Horizontal");
//Calculates the direction we want to move in, taking into account mouse movement to allow for strafing
Vector3 accelDir = (transform.forward * input_y + transform.right * input_x).normalized;
//Checks if we are not pressing any inputs, and makes us decelerate faster, to make moving feel more snappy
decelerate(accelDir);
//This code adjusts the vector to be projected onto the plane that we are currently moving on. Makes strafing better
RaycastHit hit;
Physics.Raycast(collidr.center, Vector3.down, out hit, 1000);
accelDir = Vector3.ProjectOnPlane(accelDir, hit.normal).normalized;
//Finds the current velocity of our RIgidBody
Vector3 curVel = rb.velocity;
//Determines whether or not we want to use the air movement(ignore friction) or not.
//The boolean checks if we have just jumped, so while we are still on the ground, we don't want to calculate friciton
if (isGrounded() && jumpy == false)
{
_velocity = MoveGround(accelDir, curVel);
}
else
{
_velocity = MoveAir(accelDir, curVel);
}
//Apply Movement
rb.velocity = _velocity;
//These call the rotation functions below, one rotates the camera in the y plane, the other the rigidbody in the x plane, which has the camera as a child
cameraRotate();
rbRotate();
jumpy = false;
}
private Vector3 MoveGround(Vector3 accelDir, Vector3 prevVelocity)
{
// Apply Friction
float speed = prevVelocity.magnitude;
if (speed != 0) // To avoid divide by zero errors
{
float drop = speed * _friction * Time.fixedDeltaTime;
prevVelocity *= Mathf.Max(speed - drop, 0) / speed; // Scale the velocity based on friction.
}
return Accelerate(accelDir, prevVelocity, groundAccelerate, maxVelocityGround);
}
private Vector3 MoveAir(Vector3 accelDir, Vector3 prevVelocity)
{
return Accelerate(accelDir, prevVelocity, airAccelerate, maxVelocityAir);
}
private Vector3 Accelerate(Vector3 accelDir, Vector3 prevVelocity, float accelerate, float max_velocity)
{
float projVel = Vector3.Dot(prevVelocity, accelDir); // Vector projection of Current velocity onto accelDir.
float accelVel = accelerate * Time.fixedDeltaTime; // Accelerated velocity in direction of movment
// If necessary, truncate the accelerated velocity so the vector projection does not exceed max_velocity
if (projVel + accelVel > max_velocity)
{
accelVel = max_velocity - projVel;
};
return prevVelocity + accelDir * accelVel;
}
//Function to check if we are on the ground
public bool isGrounded()
{
return Physics.Raycast(collidr.bounds.center, Vector3.down, distToGround);
//Below is a capsule cast, it would be better to implement because it has a thickness
//return Physics.CheckCapsule(collider.bounds.center, new Vector3(collider.bounds.center.x, collider.bounds.min.y, collider.bounds.center.z), collider.radius * 0.9f);
}
/// <summary>
/// decelerates us faster when not moving
/// </summary>
/// <param name="input"></param>
public void decelerate(Vector3 input)
{
if (input == Vector3.zero)
{
_friction = 10f * friction;
}
else
{
_friction = friction;
}
}
/// <summary>
/// This function is the camera rotation function
/// </summary>
public void cameraRotate()
{
//Get the input from the mouse and multiply it by sensitivity so it can be adjusted from ingame
yRot += Input.GetAxis("Mouse Y") * lookSens;
//Clamp it so that we cant just keep spinning in the Y direction
yRot = clamp(yRot, minY, maxY);
//Calculate the quaternion using the amount of rotation found before. We use the negative mouse input as the amount
//of rotation, and then specify that we want this rotation to be around the x axis. It seems counter intuitive, but this is the way to do it
Quaternion yRotAngle = Quaternion.AngleAxis(-yRot, Vector3.right);
//Apply this rotation to the cameras transform
cam.transform.localRotation = originalRotation * yRotAngle;
}
/// <summary>
/// Basically the same as above, but we dont need to clamp it because we want to be able to forever spin to the left and right
/// </summary>
public void rbRotate()
{
xRot += Input.GetAxis("Mouse X") * lookSens;
Quaternion xRotAngle = Quaternion.AngleAxis(xRot, Vector3.up);
rb.transform.localRotation = originalRotation * xRotAngle;
}
/// <summary>
/// just clamps the angle we input between the next 2 floats
/// </summary>
/// <param name="angle">the float representation of the angle</param>
/// <param name="min">the min that the angle can be</param>
/// <param name="max">you got it by now right?></param>
/// <returns></returns>
private float clamp(float angle, float min, float max)
{
return Mathf.Clamp(angle, min, max);
}
}

HoloLens Draw a graph

What is the best way to draw a graph for the HoloLens in unity?
I am new to this platform and have no idea which packages will work and which dont, the graph gets data dynamically.
EDIT: I have tried LineRenderer but it seems very limited in version 5.4 of Unity
A possible Solution for drawing a 3D-Graph is using a particle system:
Simple Example for a Component Script for a particle system:
public class Graph: MonoBehaviour {
//Particle-Resolution of the Graph
[Range(10, 100)]
public int resolution = 10;
private int currentResolution;
private ParticleSystem.Particle[] points;
void Start()
{
currentResolution = resolution;
points = new ParticleSystem.Particle[resolution];
float increment = 1f / (resolution - 1);
for (int i = 0; i < resolution; i++)
{
float x = i * increment;
points[i].position = new Vector3(x, 0f, 0f);
points[i].startColor = new Color(0f, 0f, 0f);
points[i].startSize = 0.1f;
}
}
void Update()
{
if ((currentResolution != resolution) || (points == null))
{
CreatePoints();
}
FunctionDelegate f = functionDelegates[(int)function];
for (int i = 0; i < points.Length; i++)
{
Vector3 p = points[i].position;
p.y = Sine(p.x);
points[i].position = p;
Color c = points[i].GetCurrentColor(GetComponent<ParticleSystem>());
c.g = p.y;
c.r = 1f - p.y;
points[i].startColor = c;
}
GetComponent<ParticleSystem>().SetParticles(points, points.Length);
}
private static float Sine(float x)
{
return 0.5f + 0.5f * Mathf.Sin(2 * Mathf.PI * x + Time.timeSinceLevelLoad);
}
}
A good tutorial for drawing 2D/3D graphs (including this example) with a particle system from CatLikeCoding (Jasper Flick). Refer to: http://catlikecoding.com/unity/tutorials/graphs/. It's a bit outdated and you must use startSize/startColor instead the depreceated color/size-Properties in this case.
But i'have testet it with the hololens allready and it worked fine. Some experiments with the HoloToolkit shaders for a better performance are necessary if you have a big amount of particles :-)
If you have further questions: Just ask me.

Single object 3D viewer for Google Cardboard with Unity 5

I'm trying to recreate the functionality of the Google Cardboard app’s 'Exhibit' demo. i.e. viewing a single object from all sides - look up and you see under the object, look down and you view it from above, look left or right and you see it from the side, then back.
I've tried a number of things like making the object a child of the camera, and using transform.LookAt(target); to keep the camera focused on the object but it isn't working.
New to Unity5 so any help would be very much appreciated.
UPDATE
Using code from a SmoothMouseLook script (http://pastebin.com/vMFkZJAm) this is the closest I've got so far, but it doesn't really work and feels too 'out of control' (the object keeps spinning rather than smoothly turning for inspection) and much less predictable than the 'Exhibit' demo. My guess is that I'm over complicating things. Anyone have any ideas?...
On the Camera(s) ("Main Camera") attach this to keep focused on the object:
using UnityEngine;
using System.Collections;
public class LookAt : MonoBehaviour {
public Transform target;
void Update () {
transform.LookAt(target);
}
}
On the Object, attach this script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SmoothMouseLook : MonoBehaviour
{
/*
This script is used to average the mouse input over x
amount of frames in order to create a smooth mouselook.
*/
//Mouse look sensitivity
public float sensitivityX = 1f;
public float sensitivityY = 1f;
//Default mouse sensitivity
public float defaultSensX = 1f;
public float defaultSensY = 1f;
//Minimum angle you can look up
public float minimumY = -60f;
public float maximumY = 60f;
//Minimum angle you can look up
public float minimumX = -60f;
public float maximumX = 60f;
//Number of frames to be averaged, used for smoothing mouselook
public int frameCounterX = 35;
public int frameCounterY = 35;
//Mouse rotation input
private float rotationX = 0f;
private float rotationY = 0f;
//Used to calculate the rotation of this object
private Quaternion xQuaternion;
private Quaternion yQuaternion;
private Quaternion originalRotation;
//Array of rotations to be averaged
private List<float> rotArrayX = new List<float> ();
private List<float> rotArrayY = new List<float> ();
void Start ()
{
//Lock/Hide cursor
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
originalRotation = transform.localRotation;
}
void FixedUpdate ()
{
//Mouse/Camera Movement Smoothing:
//Average rotationX for smooth mouselook
float rotAverageX = 0f;
//rotationX += Camera.main.transform.eulerAngles.x * sensitivityX;
//rotationX += Cardboard.SDK.HeadRotation.eulerAngles.x * sensitivityX;
rotationX += Cardboard.SDK.HeadPose.Orientation.x * sensitivityX;
rotationX = ClampAngle (rotationX, minimumX, maximumX);
//Add the current rotation to the array, at the last position
rotArrayX.Add (rotationX);
//Reached max number of steps? Remove the oldest rotation from the array
if (rotArrayX.Count >= frameCounterX) {
rotArrayX.RemoveAt (0);
}
//Add all of these rotations together
for (int i_counterX = 0; i_counterX < rotArrayX.Count; i_counterX++) {
//Loop through the array
rotAverageX += rotArrayX[i_counterX];
}
//Now divide by the number of rotations by the number of elements to get the average
rotAverageX /= rotArrayX.Count;
//Average rotationY, same process as above
float rotAverageY = 0;
//rotationY += Camera.main.transform.eulerAngles.y * sensitivityY;
//rotationY += Cardboard.SDK.HeadRotation.eulerAngles.y * sensitivityY;
rotationY += Cardboard.SDK.HeadPose.Orientation.y * sensitivityY;
rotationY = ClampAngle (rotationY, minimumY, maximumY);
rotArrayY.Add (rotationY);
if (rotArrayY.Count >= frameCounterY) {
rotArrayY.RemoveAt (0);
}
for (int i_counterY = 0; i_counterY < rotArrayY.Count; i_counterY++) {
rotAverageY += rotArrayY[i_counterY];
}
rotAverageY /= rotArrayY.Count;
//Apply and rotate this object
xQuaternion = Quaternion.AngleAxis (rotAverageX, Vector3.up);
yQuaternion = Quaternion.AngleAxis (rotAverageY, Vector3.left);
transform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
private float ClampAngle (float angle, float min, float max)
{
if (angle < -360f)
angle += 360f;
if (angle > 360f)
angle -= 360f;
return Mathf.Clamp (angle, min, max);
}
}
For that particular use case, you don't need a script. Assuming you are using the CardboardMain prefab, do this:
Put the object at the origin, and the CardboardMain there too.
In the Cardboard settings, set Neck Model Scale to 0.
Open up CardboardMain and select Main Camera under the Head object.
Set it's Transform Position Z value to a negative value (far enough to see the object).
(You can think of this as the "selfie-stick" camera model.)

2D projectile trajectory prediction (unity3d)

(Using unity3d 4.3 2d, it uses box2d like physics).
I have problems with predicting trajectory
I'm using:
Vector2 startPos;
float power = 10.0f;
float interval = 1/30.0f;
GameObject[] ind;
void Start (){
transform.rigidbody2D.isKinematic = true;
ind = new GameObject[dots];
for(int i = 0; i<dots; i++){
GameObject dot = (GameObject)Instantiate(Dot);
dot.renderer.enabled = false;
ind[i] = dot;
}
}
void Update (){
if(shot) return;
if(Input.GetAxis("Fire1") == 1){
if(!aiming){
aiming = true;
startPos = Input.mousePosition;
ShowPath();
}
else{
CalculatePath();
}
}
else if(aiming && !shot){
transform.rigidbody2D.isKinematic = false;
transform.rigidbody2D.AddForce(GetForce(Input.mous ePosition));
shot = true;
aiming = false;
HidePath();
}
}
Vector2 GetForce(Vector3 mouse){
return (new Vector2(startPos.x, startPos.y)- new Vector2(mouse.x, mouse.y))*power;
}
void CalculatePath(){
ind[0].transform.position = transform.position; //set frist dot to ball position
Vector2 vel = GetForce(Input.mousePosition); //get velocity
for(int i = 1; i < dots; i++){
ind[i].renderer.enabled = true; //make them visible
Vector3 point = PathPoint(transform.position, vel, i); //get position of the dot
point.z = -1.0f;
ind[i].transform.position = point;
}
}
Vector2 PathPoint(Vector2 startP, Vector2 startVel, int n){
//Standard formula for trajectory prediction
float t = interval;
Vector2 stepVelocity = t*startVel;
Vector2 StepGravity = t*t*Physics.gravity;
Vector2 whattoreturn = ((startP + (n * stepVelocity)+(n*n+n)*StepGravity) * 0.5f);
return whattoreturn;
}
Using this, I get wrong trajectory.
1. It's like gravity doesn't drag trajectory down at all, and yes i know that gravity is weak because:
t*t*Physics.gravity = 0.03^2 * vector2(0, -9.8) = vector2(0, -0.00882)
But that is the formula :S
2. Since gravity is low, velocity is too strong.
Here is the video:
http://tinypic.com/player.php?v=1z50w3m&s=5
Trajectory formula form:
http://www.iforce2d.net/b2dtut/projected-trajectory
What should I do?
I found that if I set
StepGravity to something stronger like (0, -0.1)
and devide startVel by 8
I get nearly right trajectory, but i don't want that, I need true trajectory path.
Users from answer.unity3d.com said I should ask here, because here is a bigger group of mathematical coders.
And I searched a lot about this problem (that how I found that formula).
you're only calculating the effect of gravity over 1/30th of a second for each step - you need to do it cumulatively. Step 1 should end with a velocity of 0.09G, Step 2 with .18G, step3 with .27G etc.
Here's a very simple example that draws the ballistic trajectory based on start velocity and a supplied time:
using UnityEngine;
using System.Collections;
public class grav : MonoBehaviour {
public Vector3 StartVelocity;
public float PredictionTime;
private Vector3 G;
void OnDrawGizmos()
{
if (G == Vector3.zero)
{
// a hacky way of making sure this gets initialized in editor too...
// this assumes 60 samples / sec
G = new Vector3(0,-9.8f,0) / 360f;
}
Vector3 momentum = StartVelocity;
Vector3 pos = gameObject.transform.position;
Vector3 last = gameObject.transform.position;
for (int i = 0; i < (int) (PredictionTime * 60); i++)
{
momentum += G;
pos += momentum;
Gizmos.DrawLine(last, pos);
last = pos;
}
}
}
In you version you'd want draw your dots where I'm drawing the Gizmo, but it's the same idea unless I'm misunderstanding your problem.