How to define the direction perpendicular to a GameObject's motion (Unity)? - unity3d

I'm trying to create a game where a ball is launched off from a circle, much like a cannon, but it can be launched into any direction, 360º because the circle which the ball is attached to can rotate. So, I was thinking of using Rigidbody2D.AddForce() but I'm not sure how to define the direction I want the force to be applied. I want it to be the direction perpendicular to the ball/player's movement but I don't know how to define that. Thanks for any help! :)

If you get the direction that the ball is travelling (as say degrees) you can add a certain angle to that and use the angle to determine the force that needs to be applied.
I'm assuming that the ball/player has no ridged body, if it does then you can just grab the direction directly. Also since your using circle to describe the spawned shape i'm going to assume your working in 2D.
Vector3 lastPosition;
void Update()
{
//launch the ball before updating the last position
lastPosition = transform.position;
}
Vector3 launchDirection()
{
Vector3 ballDirection = transform.position - lastPosition;
float angle = Mathf.Atan2(ballDirection.x, ballDirection.y) * Mathf.Rad2Deg;
//the direction should be perpendicular to direction of movement
float angle += 90;
return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
}
I haven't ran the code in unity but it looks like it should work. Basically to get the direction you store the last position and compare it to the current direction to work out the delta (if your using a ridged body to move around then grab the direction from that instead) then use atan2 to get the angle. To make the launch direction perpendicular to the ball I added 90 degrees (you might want -90 depending on what side you need the circle to launch from). Now that we have the angle that you want the ball to shoot out from, use that with Sin and Cos to get the XY of the angle.
There you have it that will get you the direction perpendicular to movement, you your using 3 dimensions it's basically the same maths just with a few numbers thrown in to pad the return value.
Oh if your object always faces the direction of movement transform.right also works :P

Related

Rotation flipping when moving around the sides of objects

I want to make a game in Unity where a person can pick a surface and walk along all of its sides. I've gotten the movement working, but when I rotate my character around certain angles of corner the character flips 180 degrees in some direction (it's different depending on the corner) and when I want them to move forward the game freaks out as they keep going across the corner over and over again, turning, and going forward across the border again. I'd strongly prefer to keep my character from doing these 180-degree spins and I think it's just due to a flaw in the formula I use to calculate the angle they stand at (which is based around making sure their transform.up is aligned with the point they are meant to stand on). Any ideas on how I fix this rotation formula in Update?
Current formula:
angle = Vector3.Angle(closestPoint, transform.position);
var t = transform;
var angles = t.eulerAngles;
t.LookAt(GravityWellPoint.transform.position);
t.RotateAround(transform.position, -transform.right, 90);
transform.rotation = Quaternion.Lerp(transform.rotation, t.rotation, Time.deltaTime * 5.0f);
Got this solution from a different forum and it worked:
So this is actually not a trivial problem to solve. If you try doing it by calculating angles etc you almost always end up with a similar spinning/flipping issue in certain positions. You can solve it by doing the maths, but its a pain. I usually like to use Quaternion.LookRotation to solve this kind of problem. you can feed in the desired forward and upward directions. So you can calculate the desired upward direction like so:
Vector3 targetUpDirection = transform.position - GravityWellPoint.transform.position;
Then you would do the following:
transform.rotation = Quaternion.LookRotation(transform.forward,targetUpDirection);
but this doesnt quite work. LookRotation will ensure that your forward direction is exactly the one you specify, and then chooses the upward direction that's the closest possible to the one you specify. So you will find that we don't actually manage to point our object upwards in the way we intended. However, there is an unintuitive solution we can apply instead.
Calculate the upward direction in the same way, then use LookRotation to rotate our object to point its forward face in exactly our desired upwards direction, and its upward face towards the current forward direction:
Vector3 targetUpDirection = transform.position - GravityWellPoint.transform.position;
transform.rotation = Quaternion.LookRotation(targetUpDirection, transform.forward);
Now our object is aligned perfectly, but is the wrong way up. We can use LookRotation again, to swap the upwards and forwards directions:
transform.rotation = Quaternion.LookRotation(transform.up, transform.forward);
For clarity/TLDR here is the complete code for my solution:
//find the desired up direction:
Vector3 targetUpDirection = transform.position - other.position;
//face forward/upward via black magic
transform.rotation = Quaternion.LookRotation(targetUpDirection, transform.forward);
transform.rotation = Quaternion.LookRotation(transform.up, transform.forward);

Unity - move the starting position of raycast slightly forward along its direction

I am still new to coding in unity, so please be gentle XD ... I want to make a raycast that is hitting a collider to start a new raycast with the same direction but not starting from the point where it has hit, but just slightly forward along its direction (like a few centimeters or so, or whatever that might be in unity units ^^) ... the code snippet shows the second raycast after the first hit:
Physics.Raycast(firsthit.point, direction, out var hit, distance, HitLayerMask, QueryTriggerInteraction.Ignore)
So I figure I need to change the "firsthit.point" value(s) somehow using the "direction", but I just cant figure out how exactly. Any help would be highly appreciated.
Thanks, ANB_Seth
Try:
float distance = 1f;
Vector3 newPosition = firsthit.point + direction.normalized * distance;
Physics.Raycast(newPosition, direction, out var hit, distance, HitLayerMask, QueryTriggerInteraction.Ignore);

transform.LookAt and Quaternion.LookRotation are flipping the body's rotation when looking?

I need help please, the body is flipping even though it is looking the player, I want it to be on the right rotation when looking.
Here is my code! :
Vector3 direction = Player.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(direction);
transform.rotation = rotation;
and also you can watch my video so I can explain it to you clearly!
Please help!
https://streamable.com/ygnbhq
Please watch!!!
Both as described in the API will rotate your object so its forward vector is pointing towards the target ... your 3D model seems "wrong" and doesn't have its forward (Z) vector pointing forward by default.
If I look at your model in the video I can see in the rotation Gizmo that your model is rotated by default!
It looks like the forward (Z) vector is pointing up, its right (X) vector is pointing forward and its up (Y) vector is pointing left.
That means in order to be oriented correctly it needs to be additionally rotated about -90° in its local X and -90° in its local Z axis.
You could fix that by adding the rotation needed to again make your object stand upright instead like e.g.
transform.LookAt(Player.position);
transform.localRotation *= Quaternion.Euler(-90, 0, -90);

How do I make an object instantly drop to the ground (skipping the fall animation) in Unity?

Now, I have an object wherein I only know the x and z location. If I place it at a very high y coordinate, I would get an animation of it falling down towards the ground. I want to skip this and instantly make it be on the ground. How do I do that?
Place the object at an arbitrary Y-position well above the ground, then cast a ray down to the ground and move the object to the hit position.
Pseudo-code:
transform.position.y = 200f;
if (Physics.Raycast(transform.position, -Vector3.up, out hit)) {
transform.position = hit.transform.position;
}
You could use Raycast or Boxcast to determine the distance from the bottom of your object to the next collider below it. Then just subtract this distance from the objects transform.position.y.

Unity|Moving gameobjects away from other gameobjects which are moving towards them

I have 2 AI game objects which are both capsules. Considering the first capsule AI is named X and the second capsule AI is named Y, I try to make Y move away from X (escape from him) while X is chasing Y (following him). I have no idea how to do that, I would appreciate a direction.
I tried to do what's written here, but they both move through walls even though they have capsule collider, I tried to do this:
http://forum.unity3d.com/threads/getting-objects-to-move-away-from-my-users-gameobject.142468/
but they only move in one direction and through walls.
Vector3 position = transform.position;
Vector3 targetPosition = target.transform.position;
Vector3 direction = position - targetPosition;
transform.position += direction * 2.0f * Time.deltaTime;`
You are moving them with transform.Translate. Moving the transform means "Put the object at the given position regardless of environment". If you want them to interact, you need to either use the CharacterController component and its methods or a rigidbody component and move it with force.