Unity - Matching Speed While Transistioning From Traveling on a Single Axis to Rotation Around a Circle - unity3d

I am working on a simple project that consists of a ball with a rigid body being pushed along the x axis. The ball needs to transition 90 degrees and continue straight up.
I've created a box to serve as a pivot/rotation point and placed it exactly 5 units above the beginning of the 90 degree transition from and exactly 5 units away from the end of the transition. I've created two colliders that work as triggers; one at the beginning and one at the very end of the 90 degree transition.
So my ball will come zooming along on the x axis and hit the first trigger. When it does I reset the ball's velocity to zero and parent the ball to the box serving as a pivot/rotation point. I've then applied angular velocity to the box so that the ball will rotate exactly 5 units around the pivot point. When the ball hits the second collider at the end of the transition it is un-parented and velocity is reapplied so the ball can continue straight up.
So here is the question; if the ball is 5 units away from the pivot point, the distance traveled for the 90 degree transition would be something like : 5 * 2 = the circles diameter * PI = 31.4 units distance around the circle / 4 = 7.84 game units to travel for the entire 90 degree transition.
So how do I match the velocity the ball had while traveling solely on the x axis so that it has the same speed while transitioning using the pivot point rigid body's moveRotation function around a circular axis?
If I have a velocity vector of (-10, 0, 0) when I hit the first trigger how do I calculate what to feed into the moveRotation function so that a the ball, rotating 5 units away from the pivot point, is still traveling at 10 units a second?
Taking the original velocity (-10, 0, 0) and multiplying by the distance needed to travel for the 90 degree transition(7.85 units) looks really close but I can figure out how to check it.

Related

Unity bouncing ball with scripts

how do I create a bouncing ball in unity that bounces to the same height and that I can make it fall quicker or slower? I've tried to do it from rigid body settings but the ball keeps climbing and I can't control the falling speed. Help
Multiply your desired height vector with a positive sine wave (negative values get multiplied by -1) and add this to your initial position of the ball.
To control the speed of the ball you can multiply the value you use to evaluate the sine function with another factor.
heightVector * |sin(time * speed)|

Controlling rotation path in Unity3D

On my top down 2.5D shooter game, I am usingQuaternion.LookRotation() and Quaternion.Lerp() to change the rotation of my player towards a click. The player rotates just fine, but I need more control over the rotation path. The issue here is that the LookRotation() always returns the shortest path to complete the rotation. I need the player to always rotate only in the X axis until its either +90 or -90 and then flip in the Y axis to the other side. It doesn't matter if the player rotate + or - 90 degrees over the X axis, but the idea is to always rotate in the X axis, before flipping from 1 frame to another, then rotating again in the X axis towards the click.
Here are some images illustrating the above. The "X" in red below, is where the "click" happened.

Moving a 2D physics body on a parabolic path with initial impulse in unity

What I have:
A projectile in Unity 5 2D, affected by gravity, that I want to move from point A to point B with initial impulse on a parabolic path
What I know:
The 2D coordinates of a random starting position (A)
The 2D coordinates of a random target position (B)
The time (X) I want the body to reach the target position after
What I want to know:
The initial impulse (as in unity applyforce with forcemode impulse) that I have to apply to the body onetime in order for it to reach the desired position B after X time.
Notes:
It is a 2D world using Unity 2D physics
The two positions A and B are totally random and may or may NOT be at equal heights (y coordinates)
I want to apply the impulse one time only when spawning the projectile
The projectile does NOT have any other forces affecting him other than GRAVITY (for the current problem lets assume that it always with magnitude 9.8 pointed down)
Here is a (bad) drawing of what I want :D
Thanks upfront guys!
Let's solve a few simpler problems. Our goal is to find an initial velocity for the particle, instead of an "impulse", because we'll achieve better control this way.
First, consider how we would solve this without Unity physics. A particle's position as a function of time depends on its initial position, velocity and acceleration. The same equations apply regardless of how many dimensions you have. This equation is:
current_position = 1/2 * acceleration * time^2 + velocity * time + starting_position
Let current_position be our desired destination, time be the duration of travel you choose, and the starting_position to be the starting position of the particle.
In the x-dimension, there is no acceleration. Let X_0 be our starting X position, X_1 be our destination, and T be the duration of time we want to spend getting to that destination. We want to find v_x, or the velocity in the x-dimension. For ease of interpretation, I've marked all the constants in uppercase and the variable in lowercase.
X_1 = v_x*T + X_0
v_x = (X_1-X_0)/T
In the y-dimension, we have gravity of some kind. So let's incorporate that as our acceleration:
Y_1 = 0.5*G*T*T + v_y*T + Y_0
v_y = (Y_1 - Y_0 - 0.5*G*T*T)/T
Now that you have v_x and v_y, just set the velocity:
rigidbody2d.velocity = new Vector2(v_x, v_y);
Since different objects have different mass, you don't want to try to calculate an impulse. Just set the velocity to what you want in the frame when the object is spawned.
This runs contrary to advice you might find elsewhere on the Internet, but try it first before doing something more complicated.
Some important notes:
Physics processing in Unity isn't stable: you might get different results on different platforms, especially between different mobile devices. If there is performance pressure, there may be fewer physics evaluations and therefore incorrect results. This is generally not a problem with 2D physics.
You may experience an issue with the scale of gravity, depending on your version and what other settings you have.
The formulas of position of a projectile influenced only by gravity are these:
x = x0 + v_x0*t
y = y0 + v_y0*t + 0.5*g*t^2
so, to know the starting velocity, with some basic calculations:
v_x0 = (x-x0)/t
v_y0 = (y-y0)/t + 0.5*g*t^2/t = (y-y0)/t - 4.9*t
Now, in order to add this startin velocity by using AddForce, we could have used ForceMode.VelocityChange, but this mode is only available for 3D rigidbodies, so we need to use the ForceMode.Impulse and multiplying the force by the mass of the object:
RigidBody2D rigid = GetComponent<RigidBody2D>();
rigid.AddForce(new Vector2 (v_x0, v_y0) * rigid.mass, ForceMode2D.Impulse);
and that's it.
Of course you can just set the velocity of the rigid body directly instead of using AddForce.

Matlab matrix translation and rotation multiple times

I have a map of individual trees from a forest stored as x,y points in a matrix. I call it fixedPositions. It's cartesian and (0,0) is the origin.
Given a velocity and a heading, i.e. .5 m/s and 60 degrees (2 o'clock equivalent on a watch), how do I rotate the x,y points, so that the new origin is centered at (.5cos(60),.5sin(60)) and 60 degrees is now at the top of the screen?
Then if I were to give you another heading and speed, i.e. 0 degrees and 2m/s, it should calculate it from the last point, not the original fixedPositions origin.
I've wasted my day trying to figure this out. I wish I took matrix algebra but I'm at a loss.
I tried doing cos(30) and even those wouldn't compute correctly, which after an hour I realize were in radians.
I'd try the following: In your object, you already have a property heading. Now you add another property, currentPosition (an maybe rename them to heading_robot and currentPos_robot). heading as well as currentPosition should always be relative to the original coordinate system
Then you add a new method, updatePosition that takes (newHeading, distance) as input. This method will update both heading and currentPosition, by first adding the angle in newHeading to the angle in heading, after which you update currentPosition by adding [distance*cos(heading),distance*sin(heading)] (check for signs of sin/cos here!) to the old value of currentPosition.
Finally, to get the view of the landscape (i.e. apparentPositions), you run bsxfun(#minus,fixedPositions,currentPosition) to move the origin to where the robot is at this moment, and then you multiply with the 2D rotation matrix using the angle stored in heading.
You just first translate the coordinates (-0.5cos(60),-0.5sin(60)) to take the origin to your target point.
Then rotate by multiplying the coordinates by a rotation matrix.
Of course, most programming languages use radians as angle units, so that instead of 60 you must enter 60 * PI / 180

iPhone Pong Advanced Deflection Angle

I am currently developing a simple Pong game for the iPhone. Currently using CGRectIntersectsRect for the collision detection and as for the deflection of the ball when it hits the paddle, I just multiply the ball velocity with -1 (therefore reversing the direction of the ball).
What I am trying to do is to make it so that when the ball hits the paddle, it checks whether how far is the ball from the center of the paddle, and increases the deflection angle the further the ball is away from the center of the paddle. (E.g. In this case, the ball will be deflected back at 90 degrees no matter where it came from, as long as it hits the center of the paddle)
How am I suppose to do that?
Any help would be greatly appreciated.
Thank you.
What you have given us are reference points (centre and edge). What we need are a reference line from which to measure the new angle. Additionally, what you are saying is not consistent and thus does not make sense.
I am guessing that what you are asking is a way to calculate the outgoing angle such that it is only a function of where it hit on the paddle. If it hit the paddle centre, then irrespective of the incoming angle, it will bounce off at an angle of 90 degrees to the paddle. If it hit the paddle edge, then irrespective of the incoming angle it will bounce off at an angle of 45 degrees to the paddle.
If so, then the following should do it (it is not the only way).
Assumption: The paddle shape is a rectangle.
Let L be the length of the paddle.
Let K be a constant such that L / (2 * K) = 1 / sqrt(2).
Let D be the distance from the centre of the paddle (may be + or -).
theta = pi/2 - asin (D / K);
This should give you an angle relative to the paddle.
Hope this helps.