- Home /
Clamp a player to the edge of screen when the resolution changes
Hi
I am new to using Unity (although my confidence is growing) and I am new to C#. For this project I am working on we are making a side scrolling shooter. Last night i managed to set up my GUI pause menu so it positions itself correctly when the screen resolution changes.
I want to achieve the same thing with my clamping. At the moment I have clamped the player on screen using Mathf.Clamp using this code...
private int minXValue = -8;
private int maxXValue = 8;
private int minYValue = -3;
private int maxYValue = 5;
Vector3 pos = transform.position;
pos.y = Mathf.Clamp (pos.y, minYValue, maxYValue);
pos.x = Mathf.Clamp (pos.x, minXValue, maxXValue);
transform.position = pos;
However when the resolution changes naturally the positions I have stated no longer apply (well the Y value works fine). I would like some help to clamp the player to the edge of the screen when the screen resolution changes. Thanks for reading :)
EDIT - Forgot to mention that the clamping code is inside update.
I have managed to keep the player on screen when the resolution is different thanks to this code.
Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
pos.x = $$anonymous$$athf.Clamp01(pos.x);
pos.y = $$anonymous$$athf.Clamp01 (pos.y);
transform.position = Camera.main.ViewportToWorldPoint(pos);
However I am now trying to keep the player just inside the screen edge ins$$anonymous$$d of TO the edge, so the player stays on screen fully (as in the whole mesh of the player and no part of it gets cut off by the edge of the screen) Any tips or advice??
I have managed to solve my problem. I made if statements for each of my controls (up, down left and right) and turned them off and on again when the player hit the appropriate side. I.$$anonymous$$
if (pos.x <=0.1) { leftControlEnabled = false; }
else
{
leftControlEnabled = true;
}
Thanks to robertu - I would vote up if I could. Thank you :)
Answer by robertbu · Oct 01, 2013 at 10:53 PM
Your min/max values should be floats, not ints.
A way to find the corners of the screen is to use Camera.ViewportToWorldPoint(); In order to make this work, you need to know the distance from the camera to the players. Then you can do something like:
void Start() {
Vector3 lowerLeftCorner = Camera.main.ViewportToWorldPoint(Vector3.zero, dist);
Vector3 upperRightCorner = Camera.main.ViewportToWorldPoint(new Vector3(1.0, 1,0,dist));
minXValue = lowerLefCorner.x;
maxXValue = upperRightCorner.x;
}
Another solution is to use the ratio of screen width to height. Something like:
void Start() {
float halfHeight = (maxYValue - minYValue) / 2.0;
maxXValue = halfHeight * Screen.width/Screen.height;
minxXalue = -maxXValue;
}
Note this second solution assumes the camera is centered left/right on the X axis (as indicated by your -8/8).
Thank you for your reply and information. I am still finding it hard to understand this. I tried the first solution. What is dist meant to be? Is it meant to be the new vector 3 position?
And for the second solution I get an error which informs me that $$anonymous$$XValue cannot be used in this context.
Any more help :). Thanks.
I have now actually got the clamping to work on different resolutions. THAN$$anonymous$$S!! However what happens now is that the player gets pushed slightly off screen but I want the players mesh in its entirety to stay on screen, any ideas dude??
First 'dist'. As mentioned in the writeup, 'dist' is the distance form the camera to the players. Your original code clamped the horizontal distance to -8 and 8. This would only work at a certain distance. $$anonymous$$ove the character closer to the camera, and it would go out of the camera view when at 8/-8. $$anonymous$$ove it away from the camera, and there will be extra space (assu$$anonymous$$g a perspective camera). With the default setup with the camera setting at -10 on the z axis and pointing to positive 'z', if your action occurred at Z=0, 'dist' would be 10.
As for your issue of keeping the character fully visible, I don't know why, but I have some ideas. Probably best to have you post your code and let me take a look.
Thanks for clearing that up :)
As mentioned in my edited question I have now clamped the player and I am now working on keeping them on screen fully. At the moment the player can go to this point...
But I want them to stop at this point
As requested here is my code. Just to note - the private bool playerControlEnabled is just they so I could stop the player at the exact width I wanted.
First how I am moving the player...
if (playerControlEnabled)
{
shield.Translate(Vector3.right * shieldSpeed * Input.GetAxis ("Horizontal") * Time.deltaTime);
shield.Translate(Vector3.down * shieldSpeed * Input.GetAxis ("Vertical") * Time.deltaTime);
}
Normally this is not in an if statement. And this is how they are clamped...
Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
pos.x = $$anonymous$$athf.Clamp01(pos.x);
pos.y = $$anonymous$$athf.Clamp01 (pos.y);
transform.position = Camera.main.ViewportToWorldPoint(pos);
if (pos.x <=0.1)
{
playerControlEnabled = false;
}
I was thinking of using the x position in an if statement to stop the player. What would be ideal is if I was able to prevent the player moving left when they hit 0.1 on the x axis but was still able to move in all other directions.
Your answer
Follow this Question
Related Questions
Get the originial Screen resolution, after Screen.SetResolution in mobile? 0 Answers
Pick sensible resolution for FullScreen Mac App 2 Answers
Fitting Into Different Screens 0 Answers
How to bypass resolution limits in window mode 0 Answers
how I can change the screen resolution in real time? 1 Answer