I am working on a script which makes a raycast going in the direction of the mouse. But for some reason it doesn't follow the mouse, it goes directly forward.
void Update()
{
if (Input.GetMouseButtonDown(0))
{
CastRay();
}
void CastRay()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity);
if (hit.collider != null)
{
Debug.Log(hit.collider.gameObject.name);
}
}
}
The way I understand this question is that you'd like to cast a ray from the player position towards mouse position in 2D. If that is not the case then you should edit your question and give more context on what exactly you want to achieve.
When I understood correctly then the answer is that you construct the wrong ray. What you're doing is casting a ray from the cameras perspective, you can think of it as casting a ray through your monitor towards the game world.
To get a ray from the player characters perspective, the ray should be from the players position towards the mouse position in screen space.
// get the player position in screen space
var playerScreenSpacePosition = Camera.main.WorldToScreenPoint(playerPosition);
// calculate ray direction (to - from = direction)
var rayDirection = Input.mousePosition - playerScreenSpacePosition;
// if direction vectors length should be ignored then normalize
rayDirection.Normalize();
// construct the ray with the player being the origin
// (if needed could be Ray2D as well by ignoring 'Z' axis, needs converting position and direction to Vector2)
var ray = new Ray(playerPosition, rayDirection);
// cast for a hit
var hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity);
// alternatively: if the length of the raycast shall be defined by the directions magnitude
// (only if direction not normalized, otherwise the rays length will always be one)
hit = Physics2D.Raycast(ray.origin, ray.direction, ray.direction.magnitude);
Related
I'm creating a top down 2D game, where the player has to break down trees. I made it so the player casts a ray toward the mouse, and when the ray hits a tree, it should lower the tree's health. I don't get any errors when I run the game or click, but it seems like the tree isn't detecting the hits.
void Update()
{
...
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.Raycast(playerRb.transform.position, mousePosition - playerRb.transform.position, 2.0f);
if (hit.collider != null)
{
if (hit.collider == GameObject.FindWithTag("Tree"))
{
hit.collider.GetComponent<TreeScript>().treeHealth--;
}
}
}
}
Still pretty new to coding and I'm teaching myself, so please make your answer easy to understand to help me learn.
Input.mousePosition is equal to the pixel your mouse is on. This is very different than the location your mouse is pointing at in the scene. To explain further, Input.mousePosition is where the mouse is. Think about it. If the camera was facing up, the mouse positon would be the same, but where they are clicking is different.
Instead of using Input.mousePosition, You should pass this into a function called Ray Camera.ScreenPointToRay();
You just input the mouse position and then use this new ray to do the raycast.
ANOTHER EXTREMELY IMPORTANT THING 1: Do not use Camera.main in Update(), as it uses a GetComponet call, which can cause perormance decreases. Store a reference of it in your script and use that.
Extremely important thing 2: I notice you are using GetComponent to change the tree's health. This is fine, but do not use GetComponent if you don't have to.
Like this:
Camera cam;
void Start()
{
cam = Camera.main; //it is fine to use this in start,
//because it is only being called once.
}
void Update()
{
...
if (Input.GetMouseButtonDown(0))
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray);
...
}
}
You need to convert your mouse position from screen point to world point with Z value same as the other 2D objects.
Vector3 Worldpos=Camera.main.ScreenToWorldPoint(mousePos);
Also use a Debug.DrawRay to check the Raycast
Debug.DrawRay(ray.origin, ray.direction*10000f,Color.red);
Source
I'm making a block-building system, and sometimes the blocks get offset or even clip inside each other when I place them. I'm using a ray-cast to a place where I look, and I'd like to make the ray-cast end slightly before hitting a block to prevent blocks from merging and becoming offset. The blocks I build with are also coded to be snapped to a grid.
Raycast block placement code:
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//Make Whatever a Raycast layer or if you don't want it just exclude it
if (Physics.Raycast(ray, out hit, Whatever.value))
{
Point = hit.point;
Instantiate(stoneBricks, Point, UnityEngine.Quaternion.identity);
}
}
Block grid-snap code:
Vector3 b = new Vector3(Mathf.Floor(a.x + 0.0f), Mathf.Floor(a.y + 0.0f), Mathf.Floor(a.z - 0.0f));
You might be looking for Physics.ComputePenetartion
Compute the minimal translation required to separate the given colliders apart at specified poses.
So you could do something like e.g.
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Whatever.value))
{
Point = hit.point;
// store your new bricks reference
var newBrick = Instantiate(stoneBricks, Point, UnityEngine.Quaternion.identity);
// Now check if there is an overlap
if(Physics.ComputePenetartion(newBrick.GetComponent<Collider>(), newBrick.transfom.position, newBrick.transform.rotation, hit.collider, hit.transform.position, hit.transform.rotation, out var direction, out var distance))
{
// If so move the new brick just far enough away so there is no overlapping anymore
newBrick.position += direction * distance;
}
}
Hi try increasing the offset, or try maybe increasing the collider's dimension a bit (Very tiny tiny bit).
I am casting a ray from an empty transform at the tip of a gun. The cast is to head towards the mouse position on Right Click. There is a unexpected result of the hit point being half way from expected.
I have attempted to rework the Raycasting and check out the Unity documents and forums, perhaps i am missing so simple. I have included the code of my Fire Function. Note "Raycaster" is the empty gameobject it fires from.
public void Fire(Vector3 point)
{
RaycastHit hit;
if(Physics.Raycast(Raycaster.transform.position, point, out hit))
{
Debug.DrawLine(Raycaster.transform.position, point, Color.green); //expected
Debug.DrawLine(Raycaster.transform.position, hit.point, Color.red); //actual
if(hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * weapon.Damage);
}
GameObject Impact = Instantiate(ImpactParticle, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(Impact, 1f);
}
}
The first Debug.Drawline in Green is what I expect, but the second Debug.Drawline is the actual. I must be the hit.point from the Raycast but it always is half way.
Issue example, Green is expected and red is actual
I think you use world position(point). Try convert your point argument to direction.
Vector3 dir = point - Raycaster.transform.position;
Physics.Raycast(Raycaster.transform.position, dir, out hit)
I'm making a character that follows my mouse position.
I also have enemies that are being instantiated and would like that character to move towards the location of the enemy but be a few feet higher than the enemy.
Since my character is a flying enemy I'm unsure how to use move towards in unity.
When my enemies are destroyed I would also like the character to continue following the cursor.
public class FollowCursor : MonoBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if(GameObject.FindWithTag("Enemy"))
{
transform.position = Vector3.MoveTowards.GameObject.FindWithTag("Enemy").transform.position;
}
else
{
transform.position = Camera.main.ScreenToWorldPoint( new Vector3(Input.mousePosition.x,Input.mousePosition.y,8.75f));
}
}
}
I understand you wish to move towards a flying enemy and/or have the flying enemy move towards your character.
I also understand that you wish to use the MoveTowards method to do this.
You should be able to do this by ignoring the Y position or setting it to a fixed value.
Like this.
//Method used: Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta);
//Set movespeed/steps
float speed = 5f;
float step = speed * Time.deltaTime;
//Define y position
float yourFixedYValue = 8.75f;
//Find target
Vector3 enemyPosition = GameObject.FindWithTag("Enemy").transform.position;
Vector3 target = new Vector3(enemyPosition.x, yourFixedYValue, enemyPosition.z);
//Move from current position towards target with step increment.
transform.position = Vector3.MoveTowards(transform.position, target, step);
Please elaborate what you mean if this didn't answer your question.
EDIT:
To move towards the mouse you could use a Raycast something like this inside your Update method.
if (Input.GetMouseButtonDown(0))
{ //If left mouse clicked
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //Fire ray towards where mouse is clicked, from camera.
if (Physics.Raycast(ray, out hit)) //If hit something
target = hit.point; //point is a vector3 //hit.point becomes your target
}
That "something" can be any collider, also an enemy one. So can be used to move around in general and to move towards enemies.
I have an object in my unity3d project.
Somehow its face is facing unity's down.
So if I Raycast to forward, the ray is actually pointing to object's up.
If I Raycast to down, the ray points to object's forward.
How to correct this?
Here is the code:
function Update ()
{
//scan
var fwd = transform.TransformDirection (Vector3.down);
var hit : RaycastHit;
if (Physics.Raycast (transform.position, fwd, hit, 50))
{
var distance = hit.distance;
print('distance = ' + distance);
}
else
{
print('Raycast did not hit anything');
}
}
I believe you have to change the local rotation of your object to point in the direction you want. I believe that the blue arrow represents the forward direction. :)