Limit rotation to mouse position on plane

Hi,

I’m trying to limit the rotation of an object that is looking at where the mouse hits the plane.
So simple tank with a turret. It needs to look at where the mouse hits the floor or any other object.
The camera position is almost directly above the object.

To do this I use this:

var hit : RaycastHit;
    if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit)){
	transform.LookAt(hit.point);
	}

However I don’t know how to clamp that rotation. Say limit it to left and right only. And limit that rotation to 45 degrees from the front to left and 45 degrees from front to right.

I do use rotation limitation but that’s when the object looks at another object, not at where the mouse hits an object.

newRotation.x = Mathf.Clamp(newRotation.z,-0.3,0.3);
newRotation.y = 0.0;
transform.rotation = newRotation;

I have little idea what the difference is between hit.point and a target.position so tips or the solution would be a great help!

Thanks,

Okay been trying something else.

var hit : RaycastHit;
var mouseHit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit);

Now hit.point would be where the object can look at

transform.LookAt(hit.point);

But I need to somehow get the position of that so I can use it in the new rotation

var newRotation = Quaternion.LookRotation(hit.point.position - transform.position);

But hit is not a member of ‘UnityEngine.RaycastHit’.

Any idea to make hit a position?

Okay, that doesn’t even have to work I just figured out.

I simply do that LookAt raycast hit point.
Then I do the rotation limitation

function Update () {

	var hit : RaycastHit;
	if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit)){
		transform.LookAt(hit.point);
	}

var rotation = transform.rotation;
var newRotation = rotation;

newRotation.y = Mathf.Clamp(newRotation.z,-0.1,0.1);
newRotation.z = 0.0;
newRotation.x = 0.0;

transform.rotation = newRotation;

}

Now, the problem, the turret should only go around on one axis. This works.
But with the Mathf.Clamp it still goes around. In some degrees it goes slow, but it can
still go around all the way.

Ermagherd,

My fault, my fault
newRotation.y = Mathf.Clamp(newRotation.z,-0.1,0.1);

Should of course be
newRotation.y = Mathf.Clamp(newRotation.y,-0.1,0.1);

Problem on hold, getting there. Will post when it does end up working :smile:

I would like to help, but I’m confused with your current problem.
Do you want to get the location where the ray hit, then restrict the turret’s rotation to the location of the hit point 45º in either direction?

I have code to fix exactly this. I use the default camera facing horizontal. If you are using vertical orientation then you might need to adjust the target, but I’ve included directions: line 21 and 23.

#pragma strict

//Adjust the rotation limit in degrees from 0 to 360.
// 0 is no rotation at all, 360 is full rotation.
var rotationLimit : float = 45;
private var startRot : Vector3;

function Start () {
	//Grab the starting direction for comparison.
	startRot = transform.forward;
}

function Update () {
	
	//Find where the mouse hit the ground plane.
	// In my scene there is a plane behind the turret.
	var hit : RaycastHit;
	var mouseHit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit);
	
	//Put the target at the point of the hit for x and y but leave z the same as the turret.
	var target = Vector3(hit.point.x, hit.point.y, transform.position.z);
	// if you are doing a top down like on a terrain then change it to this:
	//	var target = Vector3(hit.point.x, transform.position.y, hit.point.z);
	
	//What is the direction of my turret to the target?
	var targetDir = target - transform.position;
	
	//Compare the original direction to the current direction
	var angle = Vector3.Angle(startRot, targetDir);
	
	// if the current direction is less than our limit then we can look...
	if(angle < rotationLimit){
		//... so we look!
		transform.LookAt(target);
	}
}

BTW if your tank’s lower half moves then change the startRot to be the lower half’s transform.forward. Like this:

//Add this to the top of the script...
var lowerTank : GameObject; // Assign this in the inspector;

//Add this to your current update function
   startRot = lowerTank.transform.foward;