Ok here is my code
RaycastHit hit;
if (Physics.SphereCast(
this.transform.position,
0.5f,
this.transform.position,
out hit))
{
if(hit.collider.tag=="example tag")
{
//do something
}
}
What I want to do is move the sphere along the gameObject attached to it
the gameObject is always moving forward, that is, the positive z axis is always increasing,
so i want to keep a uniform size of sphere surrounding my gameObject
I think the mistake is with the directional vector?
can anyone help me with this. I tried searching over internet for hours ,but no luck, Thanks!
it's possible you want
transform.forward
there's an example of "transform.forward" right on the doco:
http://docs.unity3d.com/ScriptReference/Physics.SphereCast.html
Related
I'm trying to develop an FPS-arena type game. Since the start, I've implemented a raycast system for shooting an enemy, and it shoots a raycast through the center of the screen.
There is the code:
RaycastHit hit;
if (Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, gunSpecs.shotRange))
{
if (hit.collider.CompareTag(Enemy.GetTag()))
//Do something
}
Right now I've implemented a recoil system and I want to shoot the previous raycast based on the gun tip position and, instead of shooting to the center of the screen, it has to follow gun rotation.
I tried to do some calculation based on angle and similar, but I did nothing good.
This is my current code:
RaycastHit hit;
if (Physics.Raycast(gunTip.position, mainCamera.transform.forward, out hit, gunSpecs.shotRange))
{
if (hit.collider.CompareTag(Enemy.GetTag()))
//Do something
}
How can I achieve this?
EDIT 1:
This is a video of how the gun recoil works and you can see 2 raycast. The green is the working one, attacked from the gun tip to the center of the camera. The white one is attached to gun tip position to the gun tip forward. I want to achieve a raycast which start from the guntip and end at the camera.forward, but it has to follow the gun recoil movement.
https://youtu.be/_uIJ76d_4TQ
You don't unforunately. You have to do two seperate raycasts
// Get center of screen pos form main camera
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hit;
if (Physics.Raycast(ray, hit))
{
// now do second raycast from hit.point to gun.nozzle
}
Im making a space exploration game and I'm trying to have an arrow rotating around the player, pointing towards the sun in the center of the level. This is to make the game more readable.
The "arrow" is for now just a cylinder with a sphere on it - with the sphere representing the arrow point. The rotation around the player is working, but I can't get it to point towards the sun, consistently. As seen in the image here, the arrow is pointing almost opposite of where I want it to.
The code I'm using is as follows
playerPos = transform.position;
sunPos = sun.transform.position;
// Cast ray from player to sun
Ray ray = new Ray(playerPos, sunPos - playerPos);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 400, mask))
Debug.DrawLine(ray.origin, sunPos, Color.green);
Debug.Log("Distance" + hitInfo.distance);
// Rotate arrow around player.
arrow.transform.position = playerPos + ray.direction.normalized*2;
// Point arrow towards sun. This is not working
arrow.transform.rotation = Quaternion.FromToRotation(gameObject.transform.position, sunPos);
In addition to Quaternion.FromToRotation I have also tried using LookAt, which also gave me weird results. (I tried all the different up directions, i.e. LookAt(sun, Vector3.left) and (sun, Vector3.back), etc.
Hoping some clever minds can help. Thanks in advance.
Theory
You can use
Quaternion.FormToRotation
It create a quaternion (thing who handle the rotation of your gameobject) by giving a direction vector and the "0" vector. With these informations it'll know how to rotate your transform.
Exemple
I would do something like :
Vector3 direction = sunPos - playerPos;
transform.rotation = Quaternion.FromToRotation(direction, Vector3.right);
Vector3.right = (1f,0f,0f) and you should use the standard direction of your arrow. For exemple if when arrow have no rotation it point up (0f,1f,0f), you should use Vector3.up insteed.
As I said on comment you don't need raycast for this. (Maybe you need it later on your code)
Vector3 delta = sunPos - playerPos;
Vector3 direction = delta.normalized;
float distance = delta.magnitude;
So in my Unity exercise, I have to rotate a GameObject to face away from where I clicked my mouse. Also, I can only rotate around the Y-axis i.e. the GameObject is only allowed to rotate either purely to the right or purely to the left, and cannot tip towards the ground at any point. Also, I've got to do this without RayCasting (I've already done it WITH RayCasting, so as an exercise, I've got to do it without). Here's the code I've written after multiple attempts but it doesn't seem to be effective enough:
Vector3 clickLocation = Input.mousePosition;
Vector3 clickWorldLocation = Camera.main.ScreenToWorldPoint(new Vector3(clickLocation.x, clickLocation.y, transform.position.x)); //the transform.position.x is just to add some depth
transform.LookAt(new Vector3(clickWorldLocation.x, transform.position.y, clickWorldLocation.z), Vector3.up);
This code works fine if my GameObject remains in its starting position, but fails if I move it to another location and attempt the same action. Could someone help me out please?
First, call Camera.main as infrequently as you can, as it uses an expensive operation (FindGameObjectsWithTag) and doesn't cache the result.
private Camera mainCamera;
void Awake()
{
mainCamera = Camera.main;
}
To answer your question, don't use ScreenToWorldPoint in this situation, because a depth isn't most easily calculated. You don't have anything meaningful to use for the z component, and transform.position.x makes no sense here.
Instead, create a Plane that you want to click into (such as the plane parallel to the view plane and intersecting the object), use ScreenPointToRay to turn the mouse position into a Ray, then find where the ray and plane intersect. Plane.Raycast is much, much faster than a physics raycast. Then, find the direction from the mouse world position to the object, and use Quaternion.LookRotation to turn that direction into a rotation you can assign to the object's rotation:
Ray mouseRay = mainCamera.ScreenPointToRay(Input.mousePosition);
Plane mousePlane = new Plane(mainCamera.transform.forward, transform.position);
float rayDistance;
if (mousePlane.Raycast(mouseRay, out rayDistance))
{
Vector3 mouseWorldPos = mouseRay.GetPoint(rayDistance);
// make the z component of mouseWorldPos the same as transform.position
mouseWorldPos.z = transform.position.z;
Vector3 awayFromMouseDir = transform.position - mouseWorldPos;
transform.rotation = Quaternion.LookRotation(awayFromMouseDir, Vector3.up);
}
When the mouse is at the Door (red area) i want to do something. I am trying to cast a Ray but the Ray doesn't hit the Door and i cant find where exactly it is hitting. Also how can i Debug.DrawRay this ray?
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
if (hit.collider.tag == "InteractiveDoor")
{
doorInteractGameObject.SetActive(true);
}
else
{
doorInteractGameObject.SetActive(false);
}
}
You might need to create a LayerMask and add it to the parameters for Physics.Raycast; also make sure that the door has a collider on it. You would be surprised how many times I just forgot to add a collider.
In terms of drawing the ray in case this is not working for some reason. Use Debug.DrawRay. I recommend putting it in FixedUpdate() or Update(). Color and duration you can set to whatever you want but I recommend having depthTest be false since you want the ray to be drawn regardless. Then call it like:
Debug.DrawRay(ray.origin, ray.direction, <color>, <duration>, false);
You can draw this ray as:
Debug.DrawRay(ray.origin, ray.direction);
or
Debug.DrawRay(Camera.main.transform.position, Camera.main.ScreenPointToRay(Input.mousePosition).direction);
Option 1 is more direct once you've defined your ray, but option 2 gives you more choice to play around if it turns out this Ray doesn't behave the way you expect it to.
camera.ScreenPointToRay expects a Vector3 but Input.mousePosition returns a Vector2. The Unity docs on Vector3 and Vector2 appear that you should be able to use Vector2 as Vector3 implicitely and it'll populate the z component as 0, but if the Debug.DrawRay shows that the ray is the issue, then you need to append a 0. Maybe something like:
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
The fix is to go to your camera and set the tag to 'MainCamera'. Or you can modify your code to have a camera variable and use that variable instead of Camera.main.
I'm trying to detect the ground ahead of a cube that doens't have boxcollider or rigid body. I can detect it ok but the distance never changes. I can use very big number or very small ones that it still detects the ground at the same distance.
The debug lines are working fine and nothing is detected before the ground. Even trying raycast without distance keeps the detection at the same distance.
I tried some other variations of the method Raycast with the same results.
Here is my script:
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hitInfo;
Debug.DrawRay(pos, transform.forward * detectDistance, Color.green);
if (Physics.Raycast(ray,out hitInfo, detectDistance)) {
Debug.Log(hitInfo.transform.name);
Debug.DrawRay(pos, transform.forward * detectDistance, Color.red);
}
If your main goal is to calculate the distance between two GameObjects (cube and ground), the use of Raycast is not a must. You can follow this other approach:
Vector3 dist = Vector.distance(cube.transform.position, ground.transform.position);
Debug.Log(string.Format("Distance between {0} and {1} is: {2}", cube, ground, dist));
However if you want to keep with the Raycast, without having all the information about how is your scene and how are the gameObjects located, I can only recommend you to try the following things:
1- Calculate the direction of the Ray like this:
Vector3 direction = ( cube.transform.position - ground.transform.position ).normalized;
Ray ray = new Ray( cube.transform.position, direction );
2- Calculate the distance from hit:
if (Physics.Raycast(downRay, out hit)) {
float distance = hit.distance;
}
3- And just in case calculate the distance from void FixedUpdate()
The problem was the other terrain chunks wasn't generating the collider mesh till you get really close to it.
I did find a way to generate it far away.