How to change the forward direction of Raycast - unity3d

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. :)

Related

Unity2D raycast pointing at the wrong target

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);

How do I make a raycast end slightly before hitting an object in Unity3d?

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).

Unity: Adding impulse to a ball from a certain position

I'm making a 3d pool game and I stuck with this problem.
I can't find the needed function to add an impulse to a ball which will make the ball to spin.
In other words, how to set the AIM point from where I want to add the impulse?
If I use AddForce or AddTorque, it seems that it calculates it from the Center of the Ball.
But how to specify the aim point (Left english, Right english, etc...)?
And how to route the ball to the camera direction after a cue hit the ball?
At first look I think you should check Rigidbody.AddForceAtPosition. You should calculate the aim points somehow in world coordinates also.
I am relatively new on Unity but the main idea came to my mind first rotate the cue vector by y axis by a small amount angle, then calculate the hit point for each regions by casting physics ray then finally apply impulse by using Rigidbody.AddForceAtPosition. I tried to write a sample code:
public class SphereController : MonoBehaviour {
private Vector3 cueStartPoint;
void Start () {
cueStartPoint = new Vector3(0, 0.5f, -13f);
}
void Update () {
//direction from cue to center
var direction = transform.position - cueStartPoint;
//rotate cue to aim right english
var angleForRightEnglish = 5f;
var directionForRight = Quaternion.AngleAxis(angleForRightEnglish, Vector3.up) * direction;
Debug.DrawRay(cueStartPoint, directionForRight, Color.red, 10f);
//rotate cue to aim right english
var angleForLeftEnglish = -5f;
var directionForLeft = Quaternion.AngleAxis(angleForLeftEnglish, Vector3.up) * direction;
Debug.DrawRay(cueStartPoint, directionForLeft, Color.blue, 10f);
//try a sample hit from right
if (Input.GetKeyDown(KeyCode.RightArrow)) {
var forceMagnitude = 1f;
var hitForce = forceMagnitude * directionForRight.normalized;
//calculate right hit point on sphere surface
RaycastHit hitInfo;
if (Physics.Raycast(cueStartPoint, directionForRight, out hitInfo)) {
var rightHitPoint = hitInfo.point;
gameObject.GetComponent<Rigidbody>().AddForceAtPosition(hitForce, rightHitPoint, ForceMode.Impulse);
}
}
//try a sample hit from left
if (Input.GetKeyDown(KeyCode.LeftArrow)) {
var forceMagnitude = 1f;
var hitForce = forceMagnitude * directionForLeft.normalized;
//calculate left hit point on sphere surface
RaycastHit hitInfo;
if (Physics.Raycast(cueStartPoint, directionForLeft, out hitInfo)) {
var leftHitPoint = hitInfo.point;
gameObject.GetComponent<Rigidbody>().AddForceAtPosition(hitForce, leftHitPoint, ForceMode.Impulse);
}
}
}
}
this script should be added to ball as component of course, hope this helps.

Vector3.MoveTowards while also following cursor?

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.

Unity - Get Local Mouse Position from the center of the Gameobject clicked on

I want to get the mouse clicked position from the center of the gameobject, say a Sphere of Scale(1, 1, 1), for instance. If I click on the center of the sphere it should return the x component as zero, on clicking to the extreme left of the sphere, it should return -0.5 as the x component of the vector3 and 0.5 on clicking the extreme right of the sphere. The below code helps me achieve this when at origin. However, there is one constraint for it. The Sphere has to be positioned at (0, anything, anything) (as I am concerned with the x axis).
Any help on how can I achieve this regardless of the Sphere position?
bool isGameOver = false;
float pointX;
// Update is called once per frame
void Update () {
if(!isGameOver){
RaycastHit hit;
if(Input.GetMouseButtonDown(0)){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit)){
if(hit.transform.tag =="Ball"){
pointX = transform.InverseTransformPoint(hit.point).x;
}
}
}
}
}
Are you using a perspective camera or ortographic?
If you are using perspective and you move your game object to right, you cant hit on the 0,5 of the right side. Because is behide your visible part of ball.
Only can do it with orto camera
Your code is ok for this.
If you need the object position only need to add the transform.localposition to your pointX.
pointX = transform.localPosition.x + transform.InverseTransformPoint(hit.point).x;
Use this code to rotate your gameobject looking for the camera and you get now the right x coordinate you need.
void Update () {
if(!isGameOver)
{
Vector3 offset = transform.position - Camera.main.transform.position;
transform.LookAt(transform.position + offset);
RaycastHit hit;
if(Input.GetMouseButtonUp(0)){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit)){
if(hit.transform.tag =="Ball")
{
pointX = hit.transform.InverseTransformPoint(hit.point);
Debug.Log ("X:" + pointX.ToString());
}
}
}
}
}