Im trying to get my GameObject to point towards the mouse. It has a child object with a sprite. The childs rotation is set to 0 on all zxis. The sprite points upwards (positive X) at start. The GameObject rotates with the mouse pointer but its always turning its right side towards the mouse pointer. Also when i add force forward it accelerates at the same direction the sprite is pointing which as stated before is not the direction the mouse is. What is my code missing?
var cam = Camera.main;
// Distance from camera to object. We need this to get the proper calculation.
float camDistance = cam.transform.position.y - transform.position.y;
// Get the mouse position in world space. Using camDis for the Z axis.
Vector3 mouse = cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, camDistance));
float AngleRad = Mathf.Atan2(mouse.y - transform.position.y, mouse.x - transform.position.x);
float angle = (180 / Mathf.PI) * AngleRad;
rb2d.rotation = angle;
Your shape is rotated by 90 degrees due to the way that your calculations resolve the angle, you can account for this by using:
rb2.rotation = angle - 90;
Related
I am working on combat mechanics in a Top Down 2D game. I want to create a circle around a player and move the object on the edge of that circle. No matter where your mouse is, the object always stays on the edge. How would I do that? I know this is related to math but I am yet inexperienced to implement it on the right way. Here is a picture of the idea and the question itself. Picture.
It would be nice to know how does the user controls the player.
Anyway, here's some piece of code that i used on a 2D project of mine. Not sure if it works on 3D, but even if it doesn't, the logic is the same
float radius = 400; //radius of circle
Vector3 playerPosition = player.transform.position; //Player's position
Vector3 centerPosition = transform.localPosition; //center of the circle
float distance = Vector3.Distance(playerPosition, centerPosition); //distance from player to the center of the circle
if (distance > radius) //If the distance is greater than the radius, it is already within the circle
{
Vector3 fromOriginToObject = playerPosition - centerPosition;
fromOriginToObject *= radius / distance; //Multiply by radius //Divide by Distance
Vector3 newPlayerPosition = centerPosition + fromOriginToObject; //all that Math
}
player.transform.localPosition = newPlayerPosition ;
I really encourage you to check the font as it have some visual explanation: https://answers.unity.com/questions/1309521/how-to-keep-an-object-within-a-circlesphere-radius.html
You will need the radius and center of the circle. Then probably some vector that defines the direction.
I recently started developing my very first top down 2d game. My problem is not knowing exactly how to get the bullet to go where the mouse is facing at the time of the activation of the bullet. I have a face mouse function as seen here
void faceMouse()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(
mousePosition.x - transform.position.x,
mousePosition.y - transform.position.y);
transform.up = direction;
}
However, I am not sure how to incorporate that if at all to be able to shoot at the location of my mouse. Thanks in advance!
You could try Quaternion.LookRotation() which creates a rotation based on a forward and upward vector (Documentation). Then you need to assing that rotation to your object. I use it something like this:
cursorPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
var forwardDirection = transform.position - cursorPos;
//Vector3.forward because is the z axis which is up/down in 2D
Quaternion playerRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);
transform.rotation = playerRotation;
I always want to keep an object in the center of view of a camera.
The object can not change its position.
The camera can be rotated.
The camera can move up and down.
The object should always be centered in the view of the camera.
So when I rotate the camera by -45°, I would like to know the Y position of the camera at which the rotated camera would still directly face the object.
I know the "horizontal" distance between the camera and the object (as this never changes), and I know the angle of the camera.
How could the "required camera position Y value" be calculated?
Thank you.
So this code works for me:
//Distance between object and camera. Y-axis is pointing up, so we use x and z coordinates.
float R = Vector2.Distance(new Vector2(obj.position.x, obj.position.z),
new Vector2(camera.transform.position.x, camera.transform.position.z));
// Lets find rotation from zero to target angle
float rAngle = Mathf.Deg2Rad * (camera.transform.rotation.eulerAngles.y + angle );
// Using minus cause when we rotate camera to the "right" we have to move it to the"left"
float x = -R * Mathf.Sin(rAngle);
float y = -R * Mathf.Cos(rAngle);
// Apply changes.
camera.transform.position = new Vector3(x, camera.transform.position.y, y);
Vector3 cameraRotation = new Vector3(0, angle,0);
camera.transform.Rotate(cameraRotation);
And as i said you easily can use https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html
So I'm trying to make the gun on the turret of my tank point towards the center of the screen just like in World of tanks where you have a crosshair for where the gun is pointing and the crosshair for the center of the screen.
The problem is that the gun crosshair which is a UI image in world space parented to the gun, doesn't exactly line up with the center of the screen which is the big crosshair in the image [enter image description here][1].
edit: so this works but how can I change it to the x axis?
public class CenterCursor : MonoBehaviour
{
// speed is the rate at which the object will rotate
public float speed;
void FixedUpdate()
{
// Generate a plane that intersects the transform's position with an upwards normal.
Plane playerPlane = new Plane(Vector3.up, transform.position);
// Generate a ray from the cursor position
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// Determine the point where the cursor ray intersects the plane.
// This will be the point that the object must look towards to be looking at the mouse.
// Raycasting to a Plane object only gives us a distance, so we'll have to take the distance,
// then find the point along that ray that meets that distance. This will be the point
// to look at.
float hitdist = 0.0f;
// If the ray is parallel to the plane, Raycast will return false.
if (playerPlane.Raycast(ray, out hitdist))
{
// Get the point along the ray that hits the calculated distance.
Vector3 targetPoint = ray.GetPoint(hitdist);
// Determine the target rotation. This is the rotation if the transform looks at the target point.
Quaternion targetRotation = Quaternion.LookRotation( targetPoint - transform.position);
// Smoothly rotate towards the target point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
}
You can also try putting your turret object as a child of camera object...
I have a script that can rotate an object by touch or mouse on it but I want to rotate the object when mouse goes over the corner of the object only. How can I do this?
The code I'm using is
private float baseAngle = 0.0f;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
Put invisible GameObjects or RectTransforms onto the corners of your object you want to rotate, and use them as the controls for the parent object.
One way of doing so would be to add colliders to the corners of your object.
Using OnCollisionStay(), you could then trigger the appropriate functions when the mouse button is pressed. I've done similar myself, and this way does work.
Another method to the madness:
You could raycast where you are clicking, if your raycast is within an appropriate distance to the corners (which you could calculate based on its dimensions) then permit the rotation on click.