I am trying to learn how to Raycast in Unity2D.
Here is my code:
Ray ray;
void Update()
{
ray = new Ray(transform.position, Input.mousePosition);
Debug.DrawRay(transform.position,Input.mousePosition);
}
This results in strange behavior.
transform.position is the Vector3 of the player object.
I want to shoot a ray from the Player Object through the Mouse Position.
However, this does not seem to work.
The line is drawn, but behaves weirdly. It does not point toward it at all. It's hard to accurately describe its behavior as anything except erratic.
What am I doing wrong?
I think there may be something wrong with putting in Input.mousePosition and directions in general. I would be very thankful for any help you can give.
Note: I am using Unity 2D.
When you use Input.mousePosition you get a Vector2 which represents the position of the mouse relative to the camera. This means the X and Y you get are actually the X and Y of the position of the mouse on the screen.
These coordinates are not world coordinates.
For example if you were to draw a ray from transform.position of a player standing at 0,0,0 to the mouse position of 500, 250 you would get a gigantic and seemingly randomly pointing ray.
To convert from where the mouse is on the screen(Screen Coordinates) to what it's pointing to in-game(World Coordinates) you can use Camera.ScreenToWorldPoint.
For example
Ray ray;
void Update()
{
// get the mouse screen pos
Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
// convert it
Vector3 worldMousePosition = Camera.Main.ScreenToWorldPoint(mousePosition);
ray = new Ray(transform.position, );
Debug.DrawRay(transform.position, worldMousePosition);
}
Related
OBJECTIVE
I am using this script I got from Unity's forums to move my camera around. It works perfectly and this is exactly the style of camera I want. Here it is in action:
https://streamable.com/j7ozps
I wanted to create a zoom effect when the user holds the right mouse button.
PROBLEM
After zooming in, the aim is off by a lot. Here's what happens:
https://streamable.com/8aiil0
MY ATTEMPT
void Update () {
if (Input.GetMouseButton(1))
{
int layerMask = 1 << CombatManager.GROUND_LAYER; // -> public const int GROUND_LAYER = 8;
Ray mouseClick = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hitInfos;
float maxDistance = 100.0f;
hitInfos = Physics.RaycastAll(mouseClick, maxDistance,
layerMask, QueryTriggerInteraction.Ignore);
mainCamera.fieldOfView = 10;
mainCamera.transform.LookAt(hitInfos[0].point);
}
else
mainCamera.fieldOfView = startingFieldOfView;
I also tried swapping the order of the LookAt and field of view assignment.
What am I doing wrong?
Seems that what you want is to zoom towards the cursor position, not towards where the ray hits which are likely not the same point. To check that out you can draw a debug cube where the ray hits, to check if the point you are looking at is the one you need, like so:
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = hitInfos[0].point;
Check Camera.ScreenToWorldPoint that gives you the worldspace point created by converting the screen space point at the provided distance z from the camera plane.
What I would try:
Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//check if this is the point you want to look at
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = point;
//look at it
mainCamera.transform.LookAt(point);
It should not mind if you are using the cam.nearClipPlane or the cam.farClipPlane in the ScreenToWorldPoint function, but I would play with that in case something is not working as intended.
Vector3 screenPoint = Input.mousePosition;
screenPoint.z = Camera.main.farClipPlane;
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(screenPoint);
I'm trying to get a sprite following my mouse position with my camera rotated at 30 on x axys, this works fine if camera have a rotation of 0,0,0 but not on 30,0,0, how I have to calculate this? I have tryed substracting to x position with no success, here is my code:
this is attached on the object I want to follow the mouse
private void FixedUpdate()
{
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(pos.x, pos.y, transform.position.z);
}
EDIT: also my camera is ortographic not perspective
ScreenToWorldPoint isn't really appropriate here because you don't already know the proper distance to put the sprite away from the camera. Instead, consider using a raycast (algebraically, using Plane) to figure where to put the sprite.
Create an XY plane at the sprite's position:
Plane spritePlane = new Plane(Vector3.forward, transform.position);
Create a ray from the cursor's position using Camera.ScreenPointToRay:
Ray cursorRay = cam.ScreenPointToRay(Input.mousePosition);
Find where that ray intersects the plane and put the sprite there:
float rayDist;
spritePlane.Raycast(cursorRay, out rayDist);
transform.position = cursorRay.GetPoint(rayDist);
Altogether:
private void FixedUpdate()
{
Plane spritePlane = new Plane(Vector3.forward, transform.position);
Ray cursorRay = cam.ScreenPointToRay(Input.mousePosition);
float rayDist;
spritePlane.Raycast(cursorRay, out rayDist);
transform.position = cursorRay.GetPoint(rayDist);
}
I am currently using mouse inputs to move a player (sphere) in a 3d world. I am doing this with a raycast and using the hit.point coordinates. This is the way I want my game to work, but it is a 3d game, so whenever I move the player, using the mouse coordinates, it won't align properly. This is due to the player being 3d and the mouse coordinates being 2d.
Here is my code:
public float speed;
public GameObject player;
private Ray ray;
private RaycastHit hit;
private Vector3 mousePos;
void Start ()
{
}
void FixedUpdate ()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit))
{
mousePos = new Vector3(hit.point.x, /*Insert Code*/, hit.point.z);
if(mousePos != player.transform.position)
{
player.transform.position = Vector3.MoveTowards(player.transform.position, mousePos, speed * Time.deltaTime);
}
}
}
My question is this:
If I have the player at 1.3f above the ground, how can I manipulate Vector3.MoveTowards so the mouse is centered in the player without affecting the height of the player (1.3f)?
I tried using player.transform.position.y, but it placed the mouse directly under the player (the x and z values worked, but the y-value didn't).
I, also, tried hit.point.y, but it gave me values greater than the player height (1.3f).
This might not be the best way to solve my issue but it solves it for now. I made a plane with a y value of 1.3f and put it through the player object. I, then, made the object invisible. Now, the raycast will hit that object instead of the ground.
I'm trying to move a object to the mouse position. But it's giving me large x value like 300 but at that place the pre placed object's x position is -4.
rigidBody.velocity = new Vector3(Input.mousePosition.x, EndPointY, 0)*4;
So how can I get the current mouse position?
Thank you..
Input.mousePosition will give you the position of the mouse on screen (pixels). You need to convert those pixels to the world units using Camera.ScreenToWorldPoint().
You can follow this link to learn how to drag a 3d object with the mouse or you can copy this code to move an object from the current position to the mouse position.
//the object to move
public Transform objectToMove;
void Update()
{
Vector3 mouse = Input.mousePosition;
Ray castPoint = Camera.main.ScreenPointToRay(mouse);
RaycastHit hit;
if (Physics.Raycast(castPoint, out hit, Mathf.Infinity))
{
objectToMove.transform.position = hit.point;
}
}
The conversion with ScreenToWorldPoint is straight-forward for 2D Vectors:
Vector2 screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Vector2 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
That is the current mouse position. The issue is that your objects are in world coordinates and the mouse is using screen coordinates.
You need to convert the mouse position using Camera.ScreenToWorldPoint().
If you wanted to use the new Unity InputSystem you could do the following:
using UnityEngine;
using UnityEngine.InputSystem;
...
Vector2 screenPosition = Mouse.current.position.ReadValue();
Vector2 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition)
Note that you need to install the InputSystem package for this to work.
Vector3 MousePosInWorldSpace()
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
ScreenToWorldPoint returns a point in world space, at the provided z distance from the camera.
Since Input.mousePosition.z position is always 0, in the above example, the z value of the returned point would equal to the z position of the camera.
In the following example Camera.main.nearClipPlane distance is provided as the z distance from camera for the returned world space point. The camera cannot see geometry that is closer to this distance.
Vector3 MousePosInWorldSpace()
{
Vector3 mousePos = Input.mousePosition;
return Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, Camera.main.nearClipPlane));
}
I am making a top down shooter with a 45 degree camera angle. In my scene I have the camera childed to the player to follow the player. I have seen in a couple of games like "Secret Ponchos" where the camera slightly floats to the direction the player is aiming. It's subtle but adds polish.
I have tried a couple of different ways but don't know how to get the Vector for the Lerp.
Is there a way I can base the nudging based on mouseMovement? If so How?
To get the position to use for the Lerp of your camera control, you just need to figure out the direction you want the camera to nudge in and add that to the player's position.
One option is to use transform.forward to use the direction your player is facing however this requires you to rotate your player character.
//Assign the player's transform here
public Transform Target;
Vector3 GetNudgeDirection () {
return Target.forward;
}
Another method would be to get the direction of the mouse relative to the player.
public Transform Target;
Vector3 GetNudgeDirection () {
//Get the position of the mouse
Vector3 mousePos = Input.mousePosition;
mousePos.z = -Camera.main.transform.position.z;
Vector2 inputPos = Camera.main.ScreenToWorldPoint(mousePos);
//returns direction from the player to the mouse pos.
return (inputPos - (Vector2)Target.position).normalized;
}
You would then add the nudge direction to the target's position to get where your camera should aim at.
//This field determines how far to nudge
private float nudgeDistance = 2f;
Vector3 GetTargetPosition () {
return Target.position + (GetNudgeDirection() * nudgeDistance);
}
Keep in mind the target position is where your camera should look, not where it should move to! So when you are actually moving your camera, add an offset to the target position so it maintains its distance.