I used to raycast to destroy things in my game and it didn't work unless I moved quite fast I attached this script to my main camera in unity, Can anyone tell me what I have done wrong as I want it to happen regardless of movement whether you're still or not.
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector2 mousePos = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
RaycastHit2D hit = Physics2D.Raycast(mousePos, Vector2.zero, 100f);
if (hit.collider.tag == "Ground")
{
Debug.Log("You clicked a block and tried to break it!");
Destroy(hit.collider.gameObject);
}
}
}
Physics2D.Raycast should be used in FixedUpdate because in there is when the physics are calculate. Physics are not frame dependant.
From the docs:
RaycastHit2D Raycast(Vector3 origin, Vector3 direction, float distance)
You've given the raycast a zero direction.
Generally, you should use ScreenPointToRay and pass the ray origin and direction to Raycast instead
Related
I started a new game project, and I have tried to find a way to only use a rigidbody2D component to move my player game object instead of using transform.position. And I can't come up with a good way to do it or find a tutorial or documentation about it.
I have got it to work with transform.position, but how could I do it with rigidbody2D?
For movement with RigidBody2D you have mutiple options which are physics based.
I assume that's the reason you want to use RigidBody2D in the first place.
RigidBody2D obj = GetComponent();
private void moveBody()
{
//direction towards your goal
Vector2D v = mousePosition - transform.position;
//Example 1 set the velocity
obj.velocity = v;
//Example 2 apply force
obj.AddForce(v, ForceMode2D.Impulse);
}
you can read more about RigidBody2D movement
here
You can throw an invisible collider on your stage and move your object to the position you want with the ray.
Ray ray;
public RaycastHit hit;
private void Update()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f))
{
Debug.DrawRay(Camera.main.transform.position,hit.point);
transform.position = hit.point;
}
}
Best.
I'm attempting to make a raycast for a laser that will have some level of inaccuracy when fired. I was doing this with a method that creates a vector3 with some random values and adding it to the forward direction of the object firing the laser. This however seems to occasionally make the raycast clip through the object without hitting it. The code I added is debug testing to figure out this problem.
private void FixedUpdate()
{
Vector3 attackDirection = transform.TransformDirection(Vector3.forward + new Vector3(0.2f, 0.0f, 0.0f));
RaycastHit hit;
if (Physics.Raycast(transform.position, attackDirection, out hit, Mathf.Infinity))
{
Debug.DrawLine(transform.position, hit.point);
}
else
{
Debug.DrawLine(transform.position, attackDirection * 50);
}
Vector3 directionToTarget = (target.transform.position - transform.position);
Aiming(directionToTarget);
OrbitAroundTarget();
}
The object firing the raycast is orbiting around the object it's supposed to be hitting.
Both objects have box colliders and rigidbodies that are kenetic.
This is also happening if the code is executing in FixedUpdate or Update.
The Aiming method makes the object Quaternion.Slerp to look at it's target and the Orbit method makes the object transform.RotateAround it's target.
I have a box that fires a 2D raycast forward every few seconds, and want it to detect the player's rigidbody2D. I am able to get the raycast firing (the debug draws it correctly), but for some reason it is not detecting the player's rigidbody2D component.
void Shoot()
{
// convert this object's Rigidbody2D [_rb] rotation to radians
float rad = _rb.rotation * Mathf.Deg2Rad;
// use some math I found who-knows-where to make a Vector2 projecting forward
Vector2 firingAngle = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
// project a 2D raycast from the position of the Rigidbody2D out to [range]
RaycastHit2D hit = Physics2D.Raycast(_rb.position, firingAngle, range);
if (hit.rigidbody != null)
{
// **This part of the code never runs, even if the player is clearly intersecting the raycast.**
Debug.DrawRay(this.transform.position, firingAngle*hit.distance, Color.yellow, 1f);
Debug.Log("Hit");
} else {
// **Instead, this part always runs.**
Debug.DrawRay(this.transform.position, firingAngle*range, Color.white, 1f);
Debug.Log("Did not hit");
}
}
Make sure when doing raycasts against GameObjects with a Rigidbody or Rigidbody2D component, that there is also a corresponding Collider or Collider2D component (either on the GameObject itself, or one of its children).
Otherwise, raycasts and collision events won't trigger.
Hi I want to make ricochet for my bullet. But when my bullet collides with a wall, bullet starts to fly along wall:
What did I do wrong? Here are my code parts:
public Rigidbody2D rb;
Vector2 m_dir;
private void Start()
{
m_dir = rb.GetRelativeVector(Vector2.right);
rb.velocity = m_dir * speed;
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Wall")
{
Vector2 _wallNormal = col.contacts[0].normal;
m_dir = Vector2.Reflect(rb.velocity, _wallNormal).normalized;
Debug.Log("Collide!"); // debug works
rb.velocity = m_dir * speed;
}
}
Bullet Inspector - CircleCollider2D + Rigidbody2D. Wall Inspector - BoxCollider2D + Rigidbody 2D (Kinematic)
First of all:
The default behavior in Unity physics should already ricochet the bullet from the wall without your help.
As the bullet collider is round, it should not fly in a random direction.
What causes your problem:
The problem you have, seems to come from the order in which the methods are called.
Basically unity physics first resolves the collisions for this physics frame, and afterwards calls all the OnCollisionEnter methods. (More information)
This causes your rb.velocity to already be the ricochet velocity.
When you now calculate the reflect angle with the velocity pointing away from the wall, you get an inward pointing velocity.
In essence, your bullet keeps on ricocheting from the wall, but you change direction back to the wall in every frame.
How to solve it:
Use the Collision2d.relativeVelocity instead of rb.velocity.
This is the velocity that was recordet at the time of impact instead of the changed one.
Note: As it is relative to an unmoving object, you get the absolute velocity.
m_dir = Vector2.Reflect(rb.velocity, _wallNormal).normalized;
becomes
m_dir = Vector2.Reflect(-col.relativeVelocity, _wallNormal).normalized;
I'm new in Unity3D and I have a problem with collision detection. I want to return true if i hit the obstacle by raycast and block movement in this direction. It works good when im in front of the obstacle face to face. When i'm changing direction and i'm in front of the obstacle (but with another face direction) then it returns false and i can still move in all directions (it should block "up" movement like you see on first image).
Any tips would be greatly appreciated!
Returns true when obstacle is in front of us and we can't move "up"
Returns false when obstacle is in on our left or right
Player is blocked after wrong move
Here is sample of my code:
void Update()
{
Ray myRay = new Ray(transform.position, Vector3.right);
Debug.DrawRay(transform.position, Vector3.right, Color.red);
if (Physics.Raycast(myRay, out hit, 1.5f))
{
if (hit.collider.gameObject.tag == "TerrainObject")
{
Debug.DrawRay(transform.position, Vector3.right, Color.blue);
upHit = true;
}
}
else
upHit = false;
...
}
As discussed in the comments, you need to increase the starting height of the raycast.
Use Ray myRay = new Ray(transform.position+new Vector3(0f,0.15f,0f), Vector3.right); to raycast from above the ground a little bit.