Here is the video
I'm trying to hover the player over the cursor, but it doesn't work exactly, here's the code:
var playerPlane = new Plane(Vector3.up, transform.position);
// Generate a ray from the cursor position
var 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.
var targetPoint = ray.GetPoint(hitdist);
// Determine the target rotation. This is the rotation if the transform looks at the target point.
var targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
// Smoothly rotate towards the target point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
Here is the player hierarchy
The player and his scripts:(further child objects)
mesh
the same mesh that changes position depending on the rotation of its parent
Related
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);
}
I'm trying to add dashing to the player in a Diablo-esque game I'm working on, and it "works" where you can dash towards your cursor.
if (isDashing)
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100, movementMask))
{
motor.MoveToPoint(hit.point);
motor.speed = 150;
}
}
I get the mouse position, then move to that position with enormous velocity. MoveToPoint() function uses NavMeshAgent's SetDestination(point) function and this again "works" but the problem is naturally there isn't a limit to how far you can dash. You can have the mouse way over at the end of the screen and the character will still dash there.
I figured I should be using a Vector3 to define the limits of the dash, but I can't quite nail it down. I get the direction below and then apply the magnitude, but it does not work how I imagined it would.
if (Physics.Raycast(ray, out hit, 100, movementMask))
{
float mag = (hit.point - transform.position).magnitude;
if (mag < dashLength)
{
Vector3 dir = (hit.point - transform.position).normalized;
Vector3 newVector = dir * (dashLength - mag);
motor.MoveToPoint(newVector);
}
else
motor.MoveToPoint(hit.point);
motor.agent.speed = 150;
}
Any help would be appreciated
The main issue here is that you are treating a movement vector like a position. You want to start a the current transform.position and ADD the movement vector you calculated.
Further instead of extracting and checking the magnitude you can simply use Vector3.ClampMagnitude to keep the direction but make sure that the magnitude is not greater than your dashLength like e.g.
if (Physics.Raycast(ray, out hit, 100, movementMask))
{
// Calculate the difference only once
var movement = hit.point - transform.position;
// Make sure that delta has a maximum magnitude of dashLength
movement = Vector3.ClampMagnitude(delta, dashLength);
// MoveToPoint expects a position not only the movement vector
// so you start at your current position and add the movement
var newPosition = transform.position + movement;
motor.MoveToPoint(newPosition);
motor.agent.speed = 150;
}
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'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 trying to move (fire) a sphere in the direction of a mouse click. But when I click, the sphere moves in unpredictable directions.
My code for adding the force to move the sphere:
if (Input.GetMouseButtonDown(0)){
RaycastHit hit;
/**
* We r using raycasting to detect mouse click on plane
* */
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit)){
newPosition = hit.point;
this.GetComponent<Rigidbody>().AddForce( (newPosition).normalized * 25, ForceMode.Impulse );
}
}
You've supplied an incorrect argument for Rigidbody.AddForce(). The vector you supply for the first argument should not be the position you want the force to point towards - it should be the direction of the force, multiplied by the magnitude.
In this case, you can calculate the direction of the force by subtracting the current position of the object from the target position:
Vector3 forceDir = newPosition - transform.position;
this.GetComponent<Rigidbody>().AddForce( forceDir.normalized * 25, ForceMode.Impulse );
Hope this helps! Let me know if you have any questions.