- Home /
How does LookRotation work in relation to ray cast?
I have a simple look at mouse cursor script that I'm trying to use to aim a turret by rotating on the Z-axis. Except I'm having some troubles with getting it to rotate correctly. Here is the script:
using UnityEngine;
using System.Collections;
public class LookAtMouse : MonoBehaviour {
public float speed;
void FixedUpdate ()
{
Plane playerPlane = new Plane(Vector3.up, transform.position);
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float hitdist = 0.0f;
if (playerPlane.Raycast (ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
targetPoint.z = 0;
Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.time);
}
}
}
The turret is just a simple place holder I made in Blender- one horizontal cylinder with two barrels attached pointing up. The purpose of the script is to make the barrels aim at the mouse cursor while only rotating on the Z-axis. I can't get that to happen no matter how I change the transform position of the plane.
I could be wrong, shouldn't Vector3.up tell the cylinder to look a long the Y-axis? That is the direction that my barrels are pointing and shouldn't setting targetPoint.z = 0 lock rotation to the Z-axis? I think the problem is with the transition from Blender to Unity- from Z-up to Y-up, as the cylinder rotates but the barrels are never looking at the mouse.
1) Given your geometry here, I have to assume this a top down game. If it isn't, then this code will not work.
2) To eli$$anonymous$$ate the mesh from the issue. Take a cube and make it long on the 'z' sides and narrow on the 'x' and 'y' to act as your barrel. Typically when testing alignment issues before I have meshes, I'll put a small sphere on the front side so I can see which is forward. Use this to test your code. If this works, and your Blender models don't, then you know the issues is the models.
3) 'targetPoint.z=0' will only work if your model is at 'z' = 0. If it isn't, then you need to set targetPoint.z to transform.position.z.
4) For your LookRotation(), you want to specify the optional 'up' parameter, and you want to use Vector3.forward. So it will be: '`Quaternion.LookRotation(targetPoint - transform.position, Vector3.forward);`'.
5) Though is probably a given, this code only works if the turret is axigned with the world 'X' and 'Y' axes.
I've tried your testing method and it appears to be the script. $$anonymous$$y game is a 2D perspective but it isn't top down. It's front perspective, like a 2D platformer- Y is up, X is horizontal, Z is the 3D space. So does that mean I'm misunderstanding the use of this script?
And to tbkn, thank you very much for sharing your script but it gives me the error: "NewBehaviourScript.GetRotationDirection() is marked as an override but no suitable method found to override"
Removed the override keyword, like I said it was copied from my script in which the object inherited from another class...
Answer by Tomer-Barkan · Oct 18, 2013 at 06:47 AM
Here's the code I use to rotate the player object to the mouse:
protected Vector3 GetRotationDirection() {
Vector3 playerScreenPosition = Camera.main.WorldToScreenPoint(transform.position);
Vector3 mouseScreenPosition = Input.mousePosition;
mouseScreenPosition.z = 0;
Vector3 toMouse = mouseScreenPosition - playerScreenPosition;
return toMouse;
}
public void Rotate() {
Vector3 target = GetRotationDirection();
// if turning 180 degrees, tell it to turn right otherwise it might turn on another axis than Z axis
if (Vector3.Angle(transform.up, target) > 179) {
target = transform.right;
}
Vector3 newUp = Vector3.RotateTowards(transform.up, target, rotateRate * Mathf.Deg2Rad * Time.deltaTime, 0);
transform.up = newUp;
}
Removed override keyword that was leftover from my own script.