Limit a rotation (transform.Rotate with Input.GetAxis) ? [C#]
Hello everyone :)
Basically, everything is in the question, but here's further details:
Primary question : I have a cannon that rotates horizontally and vertically when I use the GetAxis (horizontal or vertical) with keys.
How to limit a rotation using transform.Rotate and Input.GetAxis. I need different angle limits for both axis (Horizontal : can turn between -80° and 80° ; Vertical : can turn between -45° and 80°).
It is a question that has been asked a lot as I can see, but the forever beginner I am cannot make it work...
Secondary question : At first, I was working with Input.GetKey, now I work with Input.GetAxis because I've read it was better. Is it really ?. What's the best way to code a key input?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CanonBehaviour : MonoBehaviour {
public GameObject HorizontalRot;
public GameObject VerticalRot;
float rotSpeed = 7f;
void Update () {
if (Input.GetMouseButton (1)) {
rotSpeed = 35f;
} else {
rotSpeed = 7f;
}
HorizontalRot.transform.Rotate (0.0f, (Input.GetAxis ("Horizontal")) * rotSpeed * Time.deltaTime, 0.0f);
VerticalRot.transform.Rotate (0.0f, 0.0f, (Input.GetAxis ("Vertical")) * rotSpeed * Time.deltaTime);
}
}
If you think that what I have now is not the best way to go about it, let me know. I'm here to learn.
Thanks for any kind of help, that's very much appreciated :)
EDIT : Just to be clear, I don't expect a full script or anything, just a hint or a quick explanation of how that can be achieve is enough.
Have a nice day :)
Answer by Positive7 · Aug 21, 2017 at 01:50 PM
For your primary question try this :
private float speed;
private float y;
private float z;
private void Start()
{
y = transform.localEulerAngles.y;
z = transform.localEulerAngles.z;
}
private void Update()
{
speed = Input.GetMouseButton(1) ? 5f : 2f;
var horizontal = Input.GetAxis("Horizontal");
y += horizontal * speed;
y = Mathf.Clamp(y, -80, 80);
if (y < 80 && y > -80)
{
transform.localEulerAngles = new Vector3(0, y, z);
}
var vertical = Input.GetAxis("Vertical");
z += vertical * speed;
z = Mathf.Clamp(z, -45.0f, 80.0f);
if (z < 80.0f && z > -45.0f)
{
transform.localEulerAngles = new Vector3(0, y, z);
}
}
For second question : GetKey is a bool
and GetAxis is a float
between -1 and 1 it starts from zero and increase/decrease while button is pressed down. I'm not sure which one is better, if you want controller/joystick support GetAxis is great, if you want immediate respond GetKey or GetButton is better.
@Positive7
Thanks a bunch for the answer! The limitation works like a charm, and your explanation about GetAxis vs Get$$anonymous$$ey helped me a lot :) The only problem is that now, my cannon rotates around the wrong axis, but I cannot pinpoint which (maybe the world's one... ? I don't know, really).
The Cannon is composed of three parts : the one that is still and holds it, juste there for aesthetics purpose, the part that rotates horizontally and the part that rotates vertically. It's around the axis of those last two parts that I want to rotate. The weird thing is that the point of rotation of each part is placed correctly...
Do you have any idea of what is wrong? Since it's localEulerAngles, I don't really understand what's the problem. On a side note, I won't be able to mark you answer as correct since it's a comment and not a reply. If you want me to accept your answer, you may copy/paste it or whatever in a reply. You decide :)
IS the horizontal and vertical parts a child of the base part? Is the vertical part is a child of the horizontal part? I will convert my comment to answer once we solved your issue :D
EDIT: Probably the horizontal and vertical part is already rotated that would explain your issue.
EDIT2: And this should fix it :
private float speed;
private float y;
private float x;
public GameObject HorizontalGameObject;
public GameObject VerticalGameObject;
private void Start()
{
y = VerticalGameObject.transform.localEulerAngles.y;
this.x = VerticalGameObject.transform.eulerAngles.z;
}
private void Update()
{
speed = Input.Get$$anonymous$$ouseButton(1) ? 5f : 2f;
var horizontal = Input.GetAxis("Horizontal");
y += horizontal * speed;
y = $$anonymous$$athf.Clamp(y, -80, 80);
if (y < 80 && y > -80)
{
HorizontalGameObject.transform.localEulerAngles = new Vector3(this.x, y, 0);
}
var vertical = Input.GetAxis("Vertical");
this.x += vertical * speed;
this.x = $$anonymous$$athf.Clamp(this.x, -45.0f, 80.0f);
if (this.x < 80.0f && this.x > -45.0f)
{
VerticalGameObject.transform.eulerAngles = new Vector3(this.x, y, 0);
}
}
Before I try your script, here's the answer to the question : Yes the horizontal part is a child of the base part and yes, the vertical part is a child of the horizontal part.
The horizontal one is already rotated indeed, but I just changed the values of $$anonymous$$athf.Clamp and that works.
EDIT : So I've just tried your new solution, and it seems like we're getting closer. I think I should swap the horizontal and vertical object. There's also a thing with the up and down that rotates weirdly, but I think I know how to solve it... I'll try right away. :)
EDIT 2 : @Positive7 ... I said "I think I know how to solve it" like the boaster I am... and life proved me wrong xD. I did what seemed logical for me : I took the first script you've provided me, added the "HorizontalGameObject" (with y) and "VerticalGameObject" (with z), and used the "this" for the horizontal rotation since it's that one that's already rotated in the first place.
It all seemed so logical since it's the y value that changes when I rotated manually the horizontal part and the z value when I rotate the vertical part. I guess I'm missing something about euler angles.
Your answer
Follow this Question
Related Questions
How to rotate object in time / Why my Input.GetMouseButtoDown is slower than my Keyboard one? 0 Answers
My game script is fine but I'm still getting unexpected class error 0 Answers
Survival Shooter Error CS0120 1 Answer
How to make a 2D array of buttons? 2 Answers
ios app crashes on start 0 Answers