Raycast that follows rotation when adding a new vector 3

EDIT: Here is a gif that helps visualize what I am trying to achieve.

As you can see my hands snap to the ledge whenever the raycast detects an object. However when I rotate my character the raycasts don’t stay in front of my character meaning I can only snap from 1 specific rotation.


So I’ve been searching online everywhere but it seems my specific problem I can’t solve on my own.

I am making a raycast to determine when a 3d character controller has detected a ledge and can grab it. So I made a raycast that has a specific position (in front of the player and facing down). Yet now I am trying to get the raycast to always stay in front of my character rather than statically stay in the same position (rotate along with my character).

I don’t know how to place a raycast in a specific position without using Vector 3. I feel like the problem could be in the direction.

Here’s what I have so far (you can easily copy/paste this and it should work instantly):

	//bools that will be triggered by hands raycast
	public bool leftHandIK;
	public bool rightHandIK;

	//to move hands to ledge
	public Vector3 leftHandPosition;
	public Vector3 rightHandPosition;

	//to ensure hands don't go inside wall/ledges
	public Vector3 leftHandOffset;
	public Vector3 rightHandOffset;

	//to make hands properly rotate alongside ledge
	public Quaternion leftHandRotation;
	public Quaternion rightHandRotation;

void FixedUpdate () {
		RaycastHit lHit;
		RaycastHit rHit;

		//LeftHand IK check
		//set a raycast at our location, add so the raycast starts just above our head +  a little forward & casts it downwards & move that raycast to the left side
		//if the leftside raycast hits something...
		if(Physics.Raycast (transform.position + new Vector3(0.0f, 2.0f, 1f), -transform.up + new Vector3 (-0.5f, 0.0f, 0.0f), out lHit, 1f)){
			leftHandIK = true; 
			leftHandPosition = lHit.point - leftHandOffset; //the position of the lhand is wherever the raycast hits - offset so we dont go inside walls/ledges
			leftHandRotation = Quaternion.FromToRotation (Vector3.forward, lHit.normal); //this somehow calculates an appopropriate rotation for our hand
		}else{
			leftHandIK = false; //else lHandIK is not detecting anything
		}

		//RightHand IK check 
		if(Physics.Raycast (transform.position + new Vector3 (0.0f, 2.0f, 1f), -transform.up + new Vector3 (0.5f, 0f, 0f), out rHit, 1f)){
			rightHandIK = true;
			rightHandPosition = rHit.point - rightHandOffset;
			rightHandRotation = Quaternion.FromToRotation (Vector3.forward, rHit.normal);
		}else{
			rightHandIK = false;
		}
}

	void Update () {
		//Lefthand IK ray drawn
		Debug.DrawRay (transform.position + new Vector3 (0.0f, 2.0f, 1f), -transform.up + new Vector3 (-0.5f, 0.0f, 0.0f), Color.green);
		//Righthand IK ray drawn
		Debug.DrawRay (transform.position + new Vector3 (0.0f, 2.0f, 1f), -transform.up + new Vector3 (0.5f, 0.0f, 0.0f), Color.green);
	}

I’m not quite clear where you are getting stuck, let me know if this helps at all:

If you want a location Vector3, that is offset in “FRONT/SIDE/ARBITRARY OFFSET” of an object (where “front” is based on the objects rotation), you can simply use the Transform function TransformPoint: Unity - Scripting API: Transform.TransformPoint;

Vector3 localOffset = new Vector3(0,2,1);
Vector3 worldOffset= transform.TransformPoint(localOffset);

Alternatively, you could create an empty game object as a child of the character, at the offset you want. This objects local offset will remain constant, but it’s world position will be automatically transformed by it’s parent (the character object). You can then reference this object’s transform.position for your raycast start.

Edit:
Sorry I wasn’t clear. When you do your raycast you are adding transform.position plus some constant vector.

transform.position + new Vector3 (0.0f, 2.0f, 1f)
-transform.up + new Vector3 (-0.5f, 0.0f, 0.0f)

I suspect this is where you problem lies because you are adding a world-space coordinate to a model-space coordinate. Try adding the localPosition, rather than the (world)position to the constant vector. THEN transform to world coordinates e.g.:

TransformPoint(transform.localPosition + VectorConstant);
TransformPoint(-Vector3.up + VectorConstant2);

I usually have localPosition set to Vector3.Zero, in which case, the original example is equivalent to the last. My assumption, was of course, my mistake.