Rotate tank turret on key press until specific angle then stop rotation
Hi, I'm currently learning C# and Unity with a 2D tank game I'm building for experience. I was able to write a script for my tank that allows the turret to rotate over the z axis 2f and -2 if you hold R or T. The problem is I want the nose to stop rotating at a certain degree (36 and 348) so that the angle of the shot being fired is limited and the nose doesn't come off of the tank and look strange. Below is what I have so far to make the turret move, but I don't know where to go from there. Any advice would be great. Thank you
[SerializeField]
private float noseAngleP;
[SerializeField]
private float noseAngleN;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
tankRotate ();
tankStop ();
}
private void tankRotate()
{
if (Input.GetKey (KeyCode.R)) {
transform.Rotate(0,0,2f);
}
if (Input.GetKey (KeyCode.T)) {
transform.Rotate (0, 0, -2f);
}
}
private void tankStop()
{
if (noseAngleP > Quaternion.eulerAngles.z) {
transform.Rotate (0, 0, 0);
}
if (noseAngleN < Quaternion.eulerAngles.z) {
transform.Rotate (0, 0, 0);
}
}
}
Answer by ricke44654 · May 31, 2016 at 02:03 PM
@schladog - Having a look at your script, here are a couple suggestions:
I'm not sure how your private variables noseAngleP and noseAngleN are getting set (perhaps you're doing that elsewhere). You could make those public variables in your script and then set the values in the Inspector in Unity, that way you wouldn't have to change the code if you want to make adjustments to the the angles.
I would check for limiting the rotation in your tankRotate function similar to the code below. Basically, you don't let the turret move if it violates the minimum / maximum values you've set instead of allowing the rotation and then trying to stop it in the tankStop function.
private void tankRotate() {
if (Input.GetKey (KeyCode.R) && noseAngleP < Quaternion.eulerAngles.z) { transform.Rotate(0,0,2f); } if (Input.GetKey (KeyCode.T) && noseAngleN > Quaternion.eulerAngles.z) { transform.Rotate (0, 0, -2f); } }
Awesome, thanks for the comment.
First bullet. I set the number for P and N from the [SerializeField] which does the same thing as public but is ins$$anonymous$$d private (afaik). So I can set the numbers in the Inspector.
Second bullet. I realize now that 348 wouldn't really work since it's greater than 40. I think I could get it to work if the angle was negative, but once I go passed 0 it just goes to 358 and freezes. I changed the less than sign to greater than and it allows me to go to the set value (40) and move back down to 358 but once I get there I can't go back up to 40. Any thoughts?
Ah, the old flip over value. Just so I'm on the same page, the R key appears to do clockwise motion (adding value) and T key counter-clockwise motion (subtracting value)?
I'm still noobish to Unity, so there could be a better option here, but a couple approaches come to $$anonymous$$d:
Account for the flip over in your key handling code, could get a little ugly.
$$anonymous$$ake your rotation position relative to whatever angle you want your center to be. For example, let's say your turret center was at an angle of 90 degrees. Create a variable to hold your "rotation" with the center being zero. Then define a couple variables to hold your max rotation in either direction, lets say 40 degrees in either direction (so constrained between 50 and 130 degrees)... so something like maxRotateLeft=-40, maxRotateRight=40 (those could be your P & N values, I wasn't sure of your ter$$anonymous$$ology with those). Then check that "rotation" variable against your maxRotate variables in your key handling and if valid, change your transform rotation and increment / decrement your rotation variable. This way, you could set the starting (center) location of your turret at any angle (the rotation of the turret, not curRotation specifically -- it would stay at zero) and you can move the turret so much in either direction without caring about a specific angle. Does that make sense? A bit of code always helps me:
float curRotation=0; //center
float maxRotateRight=40.0f;
float maxRotateLeft=-40.0f;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.R) && curRotation < maxRotateRight) { transform.Rotate(0,0,2f); curRotation += 2f; }
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.T) && curRotation > maxRotateLeft) { transform.Rotate(0,0,-2f); curRotation -= 2f; }
Apologies if I have the keys swapped, but that's easily fixed. :) Hopefully this makes sense.
Yes! Awesome. Thank you so much. It is working correctly now!
I'm still learning C# and sometimes it's hard to think on my own!
(P)ositive and (N)egative was the idea for those, but I like $$anonymous$$ and max better.
Your answer