Can't clamp values using Input.GetAxis instead of GetKey

Hey guys,

I am trying to set up my controls using Input.GetAxis instead of GetKey becaues I wanted to play around with the Input settings and that kind of thing but for some reason I’m unable to clamp the final value no matter how I go about it.

Anyone want to have a go with the code?

void Update () {

	float h = Input.GetAxis("Horizontal") * speed;
	h *= Time.deltaTime;
	float v = Input.GetAxis("Vertical") * speed;
	v *= Time.deltaTime;
	transform.position += new Vector3 (h,v,0);
//	print (translation);



}

}

I realies it’s never going to be a question of clamping h or v because those values always revert back to one (since the controls axes are involved). I tried adding both value to some new temp values, adding those to transform.position then clamping that but still it wouldn’t work. Any ideas?

Cheers!

you can add an manual clamp by using if statements, such as:

float h = Input.GetAxis("Horizontal") * speed;
h *= Time.deltaTime;
float v = Input.GetAxis("Vertical") * speed;
v *= Time.deltaTime;

if ((h >= 0 && transform.position.x <= xMax) || (h<=0 && transform.position.x >= xMin))
{
transform.position += new Vector3 (h,0,0);
}

if ((v >= 0 && transform.position.y <= yMax) || (h<=0 && transform.position.y >= yMin))
{
transform.position += new Vector3 (0,v,0);
}

When using a gamepad, the movement code is even simpler than with the keyboard! :smiley:

void MoveWithStick(){ float h = Input.GetAxis("Horizontal") * shipSpeed * Time.deltaTime; float v = Input.GetAxis("Vertical") * shipSpeed * Time.deltaTime; this.transform.position += new Vector3 (h,v,0); float newX = Mathf.Clamp (transform.position.x, xmin, xmax); float newY = Mathf.Clamp (transform.position.y, ymin, ymax); transform.position = new Vector3 (newX, newY, transform.position.z); }

Call this method from Update(), of course, and remember to setup properly the ymin and ymax in Start(). :wink:

1 Like

Thanks a lot! I have 2 questions…

When you use transform.position you prefix the first instance with ‘this.’ but not in the second. Any particular reason for that?

Often I get errors saying that transform.position cannot be modified because it is not a variable but using a NEW Vector3 sometimes (I think) seems to make the problem go away. What gives? One moment I’m being told that I can’t modify the local transform values but then all of a sudden it does.
Ultimately you HAVE to feed whatever values back into ‘transform.position’, right? No matter how many variables you create if any, so why would there be an error related to modifying transform values at all?

Sorry if I’m not being too clear :blush:

you can add an manual clamp by using if statements,

That’s an interesting approach!

But, aren’t if statements generally the most expensive thing to do though? Especially for something as ubiquitous as character control? I would’ve assumed (in my humble experience) that a clamp would be computationally cheaper and the go-to way to go about this.

Actually is the other way around, clamp is more expensive than using if statements. The clamp uses if statements internally, by using it outside you have a better control regarding which comparison is relevant and which is not. I’ve done some testings using the StopWatch method, you can take a look if you want in this thread

1 Like

I’m asking myself the same question, and the answer is that I’m dumb, I have no idea why I used the this keyword there since it’s completely useless. :smiley:

Since you asked, I’ll elaborate about the this keyword, which is particularly confusing when approaching it for the first time.

This refers to the instance of the object in which it’s used. So, you may ask, why should I use it if, in our example, transform.position and this.transform.position both reference to the same, exact thing? The answer is: you shouldn’t, unless the variable you’re trying to use is hidden by scope.

To explain what I mean by hidden by scope, let’s look at this example:

void Update (){ MoveWithStick(transform); }

void MoveWithStick(Transform transform){ float h = Input.GetAxis("Horizontal") * shipSpeed * Time.deltaTime; float v = Input.GetAxis("Vertical") * shipSpeed * Time.deltaTime; transform.position += new Vector3 (h,v,0); float newX = Mathf.Clamp (transform.position.x, xmin, xmax); float newY = Mathf.Clamp (transform.position.y, ymin, ymax); this.transform.position = new Vector3 (newX, newY, transform.position.z); }

From Update(), I call MoveWithStick, but this time with a parameter of type Transform. Notice that I called the argument transform inside MoveWithStick on purpose - by using the same name I’ve hidden in the scope of the method the transform of the object, so that every time I use transform inside the method, I’ll change the local variable instead of the object transform.
And here’s where the keyword this becomes useful: if I want to access the variable hidden by the local one with the same name, I need to use the prefix this. in order to access the object’s transform, as I did in the last line of the code.

The 2nd way the this keyword is useful, is when you want to pass, when calling a method, the object itself from where you’re calling the method:

You can read about the this keyword here: https://msdn.microsoft.com/en-us/library/dk1507sz(VS.71).aspx - there’s a third reason when using this is useful, and it’s to do with indexers.

Regarding your second question, you should provide us with an example, since transform.position has both a getter and a setter, so you can modify its value, but only, of course, by passing a Vector3 (or Vector2) to it. If you’ve tried to change directly the x,y or z component of the position, then you get an error because those are read only.

1 Like

I missed that thread, I’ll read it with attention as soon as I have some time, your tests are quite interesting and useful.

1 Like

Hey Galandi, Thank you for considering it useful! This test is worth seeing, it is interesting how small things can optimize the game

You lost me here I’m afraid. I haven’t been calling any Methods with parameters so far and consequently wasn’t even aware you could do so. What does this accomplish?

Actually, I used the term parameter uncorrectly. And you’ve been using already quite extensively methods with parameters, even if you didn’t know that.

Formally, when a method is created, you can define any number of parameters for it to accept when it’s called.
I.E.:

void MyMethod (int a, float x, string myString){ //my code }
MyMethod thus has three parameters: an integer a, a float x and a string myString.

When you call MyMethod, you need to pass to it these values, and when you do that, the actual values passed to the parameters of the method are called arguments.
So when you write:

lives, duration, and I still have are the arguments passed to MyMethod.

Get the Input.GetAxis() method: it has only one parameter, a string, and when you write Input.GetAxis(“Horizontal”), you’re passing to the string parameter of the method the argument “Horizontal”.

That’s pretty much it. :wink:

Privacy & Terms