RayCast issues

Hello,

I have two pieces of code that are using a RayCast for detecting collisions. The first piece code is as below:

using UnityEngine;
using System.Collections;

public class RayCastTest : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
	
	if(Physics.Raycast(transform.position, Vector3.forward, Mathf.Infinity)) {
		Debug.Log("Ray Created");
	}
}

}

This script is attached to a Cube GameObject in the scene that has a RayCast Collider component attached to it.

The Second Piece of Code is as below:

void Update () {

	forward = transform.TransformDirection(Vector3.forward);
	//Debug.Log("Test");
	if(Physics.Raycast(transform.position, Vector3.forward, out hit, Mathf.Infinity)) {
		Debug.DrawRay(transform.position, forward*1000, Color.yellow);
		Debug.Log("Ray Created!");
		if(hit.transform.root.gameObject == player) {
			isThreatened = true;
		}
	}
	
	//Enemy will just Patrol if he is not threatened (by the player's presence)
	if(isThreatened == false)
		Patrol();
	else if(isThreatened == true)
		ShootPlayer();

}

The issue here is that none of the Debug.Log functions(given after the IF statements) get executed which leads me to believe that the RayCast code is failing. Am I doing something wrong here? Any help towards this will be really appreciated.

Seems like you’re confusing two different forwards:

  • transform.forward - each transform has a dynamic forward that is always 1 in the Z of the local co-ordinate space.
  • Vector3.forward - an constant vector equivalent to Vector3(0,0,1).

However, these two expressions are equal:

transform.forward

transform.TransformDirection(Vector3.forward)

This may not be the entirety of your bug though.

Note that RayCasts don’t create anything. They probe the Colliders in the scene and return the results.

Do you have any Colliders (CapsuleCollider, etc.)?

Please don’t post comments or question updates as new answers.

Warwick has given you a good answer to get started with but I think you may be a touched confused by how raycasts work.

The method you are using creates a straight line down the Z access of the game object you are calling it from. Anything getting hit by that line will return a raycast hit. For you this means that your AI will only be aware of the player if they stand directly in front of the character.

Please see: http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html

1st example

function Update () {
        var fwd = transform.TransformDirection (Vector3.forward);

        if (Physics.Raycast (transform.position, fwd, 10)) {
            print ("There is something in front of the object!");
        }
    }

The if statement here follows this syntax: Create a raycast(from this origin, in this direction, for this distance)

If an object with a colider is touched it will return true and process the block.

2nd Example (slightly edited):

function Update () {
    var hitDetails : RaycastHit;
    var fwd = transform.TransformDirection (Vector3.forward);

    if (Physics.Raycast (transform.position, fwd, hitDetails ,100.0)) {
        print("We hit something!");
        print("It was the " + hitDetails.transform.gameObject + " object at vector: " + hitDetails.point) 

    }
}

So here is pretty much the same thing, but we are adding a variable to bring back raycastHit information. See for more details on the class: http://unity3d.com/support/documentation/ScriptReference/RaycastHit.html

Now that you have the basics I recommend that you look at SphereCasts which are like “thick” raycasts. Put your player into a layer such as “player” and use a layer mask so that the raycast will only test against objects in the “player” layer.

http://unity3d.com/support/documentation/ScriptReference/Physics.SphereCast.html

Hello,
Thanks for the answer. I was able to correct the situation for the first code, but not for the second one. Here’s the scenario:-

  1. The scene has two animated Meshes (a human character). Lets assume Mesh1 and Mesh2

  2. Both have a Character Controller component.

  3. Mesh1 has a ThirdPersonControllerScript and Mesh2 has a AI Controller script(written by me).

  4. Both Meshes are placed on a ‘Floor’ Cube Mesh that has a Box collider on it.

  5. The RayCasting has to happen from Mesh2(AI) towards Mesh1(ThirdPersonControlled).

  6. Currently What is Happening :-
    (a)I adjust the character controller on Mesh1 and if the radius of the controller, just crosses the top limit of the floor, and I run the game, Mesh1 falls right through the floor.
    (b) In this case, the RayCasting actually works (from Mesh2 to Mesh1)

(c) I adjust the character controller again on Mesh1, so that it correctly alligns with the floor below, in which case it(Mesh1) does not fall through the floor when the game is run.
(d) However, in the above scenario, the RayCasting does not work.

I’m not sure what exactly is wrong as the RayCasting works/does not work just with a minor change in the Character Controller component attribute of Mesh1.

Here is the modified code I’m now using for RayCasting:-

void Update () {

	pos = transform.position;
	fwd = transform.TransformDirection(Vector3.forward);
	
	isRayCreated = Physics.Raycast(pos, fwd, Mathf.Infinity);
	
	if(isRayCreated == true) {
		tempCount++;
		//Debug.DrawRay(transform.position, forward*1000, Color.yellow);
		Debug.Log("Ray Created!");
	}
	
	//Enemy will just Patrol if he is not threatened (by the player's presence)
	if(isThreatened == false)
		Patrol();
	else if(isThreatened == true)
		ShootPlayer();

}

Could you please shed some more light on this and what I can do. Thanks so much for your help.