Unity 2D move and rotate issue - unity3d

I am working on adding a helicopter to my 2d game and I need it to move in circular motion whilst moving on the x axis as well. Below you can find the code that I am using which uses the mathematical circle equation.
angle += speed * Time.deltaTime; //if you want to switch direction, use -= instead of +=
float x = startPoint.x + Mathf.Cos(angle) * radius;
float y = startPoint.y + Mathf.Sin(angle) * radius;
transform.position = new Vector2(x + 2, y);
The helicopter is rotating correctly but I can't figure out how I can make it move along the x axis. Concept image of how it should work below:

1) Make an empty game object
2) Parent your box to the empty game object
3) rotate the box around the empty game object
4) move the empty game object to the side
If you want to avoid adding an empty parent, you can keep track of the center of rotation separately, rotate around it, and move it over time.
public class hello_rotate : MonoBehaviour
{
float angle = 0;
float radius = 1;
float speed = 10;
float linear_speed = 1;
Vector2 centerOfRotation;
// Start is called before the first frame update
void Start()
{
centerOfRotation = transform.position;
}
// Update is called once per frame
void Update()
{
centerOfRotation.x = centerOfRotation.x + linear_speed * Time.deltaTime;
angle += speed * Time.deltaTime; //if you want to switch direction, use -= instead of +=
float x = centerOfRotation.x + Mathf.Cos(angle) * radius;
float y = centerOfRotation.y + Mathf.Sin(angle) * radius;
transform.position = new Vector2(x + 2, y);
}
}

Related

Momentum and Inertia in Unity3D

So, when my i let go off my keys the controller stops like it hits a wall, i tried changing that but all that changed is that now it gets flung into outer space every time i press a key:
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 newMovement = transform.right * x + transform.forward * z;
momentum = new Vector3(characterController.velocity.x, 0, characterController.velocity.z);
newMovement.y = 0;
if (!newMovement.normalized.Equals(momentum.normalized))
{
Debug.Log("new" + newMovement.normalized);
Debug.Log(momentum.normalized);
momentum = (momentum.magnitude - 2f) > 0 ? momentum.normalized * (momentum.magnitude - 2f) : Vector3.zero;
if (newMovement.x == momentum.x)
momentum.x = 0;
if (newMovement.z == momentum.z)
momentum.z = 0;
}
else
momentum = Vector3.zero;
characterController.Move((newMovement * speed + velocity + momentum) * Time.deltaTime);
Also for some reason even though sometimes both vectors are equal they pass through the if statement(i tried using !=)(both vectors are logged on the first 2 lines of the if statement)
Use https://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html, it will gradually slow the movement to zero, depending on the value of smoothTime:
public float smoothTime = 0.3F;
private Vector3 velocity = Vector3.zero;
private Vector3 newMovement;
void Update()
{
newMovement = transform.right * x + transform.forward * z;
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
}

Rotation around 2 axes include unwanted Rotations

I want to spin an object around x and rotate y axis to a direction.
Quaternion qr = Quaternion.Euler(transform.eulerAngles.x, 0,0);
transform.rotation = Quaternion.Lerp(transform.rotation,qr,Time.deltaTime*5);
transform.rotation = Quaternion.Euler(xRotation(xRotationSpeed),
transform.eulerAngles.y, 0);
x and y Rotations combined make weird rotations and sometimes even rotate z even though I have it set to 0.
Here is an example that yawing an object while rolling.
Notice that the rotation is applied from right to left.
const float ROLL_SPEED = 120f;
const float YAW_SCALE = 60;
float _lastYawBase;
void Update()
{
var yawBase = Input.GetAxis("Horizontal");
var tsf = transform;
tsf.localRotation =
// 4. apply new yaw
Quaternion.Euler(0, yawBase * YAW_SCALE, 0) *
// 3. roll
Quaternion.Euler(ROLL_SPEED * Time.deltaTime, 0f, 0f) *
// 2. revert last yaw
Quaternion.Euler(0, -_lastYawBase * YAW_SCALE, 0) *
// 1. current rotation
tsf.localRotation;
_lastYawBase = yawBase;
}

Calculate initial velocity to set to rigid body so it reaches a target position with angle of launch, start position and target position as given

I need to shoot a ball from any height and make it bounce on a target position defined by the user. The angle of launch is also given. I've tried a couple of solutions so far:
Vector3 calcBallisticVelocityVector(Vector3 source, Vector3 target, float angle) {
Vector3 direction = target - source;
float h = direction.y;
direction.y = 0;
float distance = direction.magnitude;
float a = angle * Mathf.Deg2Rad;
direction.y = distance * Mathf.Tan(a);
distance += h/Mathf.Tan(a);
// calculate velocity
float velocity = Mathf.Sqrt(distance * Physics.gravity.magnitude / Mathf.Sin(2*a));
return velocity * direction.normalized;
}
Vector3 calcBallisticVelocityVector2(Vector3 source, Vector3 target, float angle) {
float distance = (target.Planar() - source.Planar()).magnitude;
float a = target.y - source.y - distance;
float halfGravity = -Physics.gravity.magnitude * 0.5f;
float distanceSquared = distance * distance;
float theta = Mathf.Deg2Rad * angle;
float cosSquared = Mathf.Cos(theta) * Mathf.Cos(theta);
float b = distanceSquared / cosSquared;
float speed = Mathf.Sqrt((halfGravity * b) / a);
Vector3 velocity = (target.Planar() - source.Planar()).normalized * Mathf.Cos(theta);
velocity.y = Mathf.Sin(theta);
return velocity * speed;
}
The results I'm getting is that even the ball does go into the direction is expected, it falls earlier than it should be so the speed calculated by these methods seems to be lower than what is actually required to hit the target position.
Rigidbody's mass is set to 1, Gravity is (0, -98, 0), rigid body's drag and angular drag is set to 0. What other variables could be affecting this behavior?
EDIT: One thing I forgot to mention is that I'm setting the resulting vector as rigid body's velocity, so I'm not using via the apply force method.
I adapted code gotten from here: https://answers.unity.com/questions/1131176/projectile-motion.html and now I'm getting the results I was expecting. I can always hit the target position at whatever angle I input.
private Vector3 calcBallisticVelocityVector(Vector3 initialPos, Vector3 finalPos, float angle)
{
var toPos = initialPos - finalPos;
var h = toPos.y;
toPos.y = 0;
var r = toPos.magnitude;
var g = -Physics.gravity.y;
var a = Mathf.Deg2Rad * angle;
var vI = Mathf.Sqrt (((Mathf.Pow (r, 2f) * g)) / (r * Mathf.Sin (2f * a) + 2f * h * Mathf.Pow (Mathf.Cos (a), 2f)));
Vector3 velocity = (finalPos.Planar() - initialPos.Planar()).normalized * Mathf.Cos(a);
velocity.y = Mathf.Sin(a);
return velocity * vI;
}

Two different classes with random values have the same output

I am making the Bouncing Ball using Processing. It works fine when I use the ball object once, but when I use it twice like ball1 & ball2, the balls appear on top of each other making the delusion that it is just one ball bouncing, although I'm setting their primary location and velocity a random number. So, where is the problem? (first argument is for velocity and the second is for x Coordinate)
Main class:
Ball ball1 = new Ball(int(random(0, 2)),int(random(width)));
Ball ball2 = new Ball(int(random(0, 2)),int(random(width)));
void setup() {
// Windows configurations
size(640, 360);
background(50);
}
void draw() {
// Draw the circle
ball1.display();
// Circle movements
ball1.movements();
// Movement limits
ball1.movementLimits();
// Draw the circle
ball2.display();
// Circle movements
ball2.movements();
// Movement limits
ball2.movementLimits();
}
Ball class:
float xCoordinates;
float yCoordinates;
float xVelocity;
float yVelocity;
final float gravity = 0.1;
class Ball {
Ball(int Velocity, int Coordinates) {
xCoordinates = Coordinates;
yCoordinates = height / 6;
if (Velocity == 0)
xVelocity = 2;
else
xVelocity = -2;
if (Velocity == 0)
yVelocity = 2;
else
yVelocity = -2;
}
void movementLimits() {
if (xCoordinates - 10 <= 0 || xCoordinates + 10 >= width)
xVelocity *= -1;
if (yCoordinates + 10 >= height)
yVelocity *= -0.9;
if (yCoordinates - 10 <= 0)
yVelocity *= -1;
}
void movements() {
xCoordinates += xVelocity;
yCoordinates += yVelocity;
yVelocity += gravity;
}
void display() {
background(50);
fill(255);
stroke(255);
circle(xCoordinates, yCoordinates, 20);
}
}
Problem 1:
Both of your objects are shaing the same cooridinates and velocity. They are stored globally so when one object changes it, the change is used by the other object as well. To fix this you should give your Ball class properties to hold the coordinates and velocities.
class Ball{
float x;
float y;
float dx;
float dy
public Ball(float x, float y, float dx, float dy){
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
}
}
Problem 2:
In the display function in Ball, you call background(50);. This will basicly cover the entire screan with the new background; over any previous balls which includes ball1. However, if you remove this line you'll get a kind of cool effect cause by all previous ball drawing sticking around. You should move the background(50); line to the beginning of the draw function. This way, you draw the two balls, draw over them with gray, then redraw the two balls in their new positions.

[Unity]How to draw a Ring Line in 3D

I'd like to draw the trajectory of an object that is moving circularly, but I do not know how to do it.
Could you tell me a good way?
I've not done a orbiting around something, but I am using Cos and Sin to generate static items around the object.
If you use TrailRenderer with the use of MathF cos and sin to rotate around an object.
var y = amplitude * MathF.cos(Time.timeSinceLevelLoaded * speed) + currentPosY
var x = amplitude * MathF.sin(Time.timeSinceLevelLoaded * speed) + currentPosX
I've not watched it, but "Board to bits" on youtube has a tutorial on the matter. of space orbiting for a planet playlist.
Hope this is the right direction for you.
Thank you for a lot of response.
I found it works with below...
void drawLine()
{
Vector3[] points = new Vector3[segments+1];
for (int i = 0; i< segments; i++)
{
float angle = ((float)i / (float)segments) * 360 * Mathf.Deg2Rad;
float x = Mathf.Sin(angle) * radius;
float z = Mathf.Cos(angle) * radius;
points[i] = new Vector3(x, 0f, z);
}
points[segments] = points[0];
lr.positionCount = segments + 1;
lr.SetPositions(points);
}