- Home /
RTS Camera - Zoom is not uniform, yet code is?
Hello guys, i have one question. I started working on a RTS title, and first step is to finish off camera code.. I ended up with a code that works, but zooming in feels slower then zooming out, yet the code is nearly identical + the same variable 'zoomSpeed' is used.. I don't know why this is the case..
public int scrollSpeed = 25;
public int zoomSpeed = 25;
public int zoomMin = 6;
public int zoomMax = 24;
public float smooth = 1.3f;
private Vector3 velocity = Vector3.zero;
void Update()
{
Vector3 temp = this.transform.position;
if(Input.GetAxis("Mouse ScrollWheel") > 0)
{
temp.y -= 100f * zoomSpeed * Time.deltaTime;
}
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
temp.y += 100f * zoomSpeed * Time.deltaTime;
}
Debug.Log(temp);
if (temp.y <= zoomMin)
temp.y = zoomMin;
if (temp.y >= zoomMax)
temp.y = zoomMax;
this.transform.position = Vector3.SmoothDamp(this.transform.position, temp, ref velocity, smooth);
}
Any ideas? Also, bonus points if anyone can point me if something I could have done better/faster..
Thanks!
First off, kudos to you iwaldrop for helping me out! :) "temp.y += zoomSpeed * Input.GetAxis("$$anonymous$$ouse ScrollWheel")" -> worked like charm, although I had to change += to -=..
However, after replacing my checking code with yours "temp.y = temp.y >= zoom$$anonymous$$ax ? zoom$$anonymous$$ax : zoom$$anonymous$$in;" Zoom stopped working.. :/
And a question, yeah I do use different values, zoom$$anonymous$$in and zoom$$anonymous$$ax, but just to bound the zoo$$anonymous$$g range.. I don't really see how I'm affecting zoom speed with it.. :/
Hope you can elaborate more on that, Thanks a lot anyway :)
Ha! That second part won't work at all! :) Sorry about confusing you.
About SmoothDamp, however...http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.SmoothDamp.html. The second value passed in is the target position. So if you're assigning temp.y as either zoom$$anonymous$$in or zoom$$anonymous$$ax then you are effectively giving it targets at different magnitudes from your current position depending on whether you are scrolling up or down.
Heh no worries =)
Okay, I see what you're saying.. I commented out whole checking zoom code and it worked.. Now the question is, is there a way around it? To still use SmoothDamp, to still have 2 different values - for $$anonymous$$ zoom and max zoom, and yet to zoom in % out at same speeds? :/
Thanks again iwaldrop, you're really helpful..
Ahh...that makes sense. Well, ok then; place this line after you move your transform.
if (transform.position.y > zoom$$anonymous$$ax)
transform.position = new Vector(transform.position.x, zoom$$anonymous$$ax, transform.position.z);
Also create a varient to check the zoom$$anonymous$$in (in a similar, but opposite manner) and you should be good to go. You might also want to check if temp.y != 0 in order to even do any of that stuff. Since you're in an Update loop you want to do as little work as possible!
EDIT: Although now I see what you were tying to do in the beginning! :) There is no reason your way shouldn't work either.
If you add a conditional early on in your update loop then you should be able to skip moving the camera at all if you're already at your upper/lower limits.
void Update()
{
Vector3 temp = transform.position;
temp.y -= zoomSpeed * Input.GetAxis("$$anonymous$$ouse ScrollWheel");
if (temp.y < zoom$$anonymous$$ax || temp.y > zoom$$anonymous$$in)
{
// do your stuff here
}
}
I'm glad you got it working. Think you could thumb up some of my helpful comments? I'm something of a karma whore! :) Cheers!
Answer by iwaldrop · Jan 16, 2013 at 07:50 PM
well, if GetAxis("Mouse Scrollwheel") returns 1 or -1, then you can multiply your scroll speed by that and do it all in one line.
void Update()
{
Vector3 temp = this.transform.position;
temp.y += zoomSpeed * Input.GetAxis("Mouse ScrollWheel");
Debug.Log(temp);
temp.y = temp.y >= zoomMax ? zoomMax : zoomMin;
transform.position = Vector3.SmoothDamp(transform.position, temp, ref velocity, smooth);
}
EDIT: Oh...and your camera is zooming at different speeds because you assign two totally different values to temp.y. Namely zoomMin and zoomMax.
I just give both of you an upvote so now it should be possible to vote for each other ;) In addition i've converted your first comment into an answer.
Answer by Bunny83 · Jan 17, 2013 at 12:47 AM
The answer is quite simple ;)
Use a seperate zoom variable. With the scrollwheel you set a target zoom level and the smoothdamp function will smooth it, but you have to remember the target zoom level across frames.
float zoom;
void Start()
{
zoom = (zoomMin + zoomMax) * 0.5f; //init value
}
void Update()
{
Vector3 temp = transform.position;
//Apply the scrollwheel and change the local zoom variable
zoom -= zoomSpeed * Input.GetAxis("Mouse ScrollWheel");
// clamp the zoom var to keep it between Min and Max
zoom = Mathf.Clamp(zoom, zoomMin, zoomMax);
// create the "target" vector for SmoothDamp
temp += new Vector3(Input.GetAxis("Horizontal") * scrollSpeed * Time.deltaTime,
zoom,
Input.GetAxis("Vertical") * scrollSpeed * Time.deltaTime);
// move the camera with moving mouse out of screen bounds
if (Input.mousePosition.x < ScrollArea)
temp += Vector3.right * -scrollSpeed * Time.deltaTime;
if (Input.mousePosition.x >= Screen.width - ScrollArea)
temp += Vector3.right * scrollSpeed * Time.deltaTime;
if (Input.mousePosition.y < ScrollArea)
temp += Vector3.forward * -scrollSpeed * Time.deltaTime;
if (Input.mousePosition.y > Screen.height - ScrollArea)
temp += Vector3.forward * scrollSpeed * Time.deltaTime;
transform.position = Vector3.SmoothDamp(transform.position, temp, ref velocity, smooth);
}
Note: You smooth your movement twice. First you increment the temp vector via delta time which already gives you a smooth progression over time. In Smoothdamp this movement get's smoothed a second time. This makes it difficult to set a clear independent speed for the movement.
I would probably just use Mathf.SmoothDamp on the y component and set x and z directly (which are already smoothed).
Something like that:
float zoom;
float velocity = 0.0f;
void Start()
{
zoom = (zoomMin + zoomMax) * 0.5f; //init value
}
void Update()
{
Vector3 temp = transform.position;
zoom -= zoomSpeed * Input.GetAxis("Mouse ScrollWheel");
zoom = Mathf.Clamp(zoom, zoomMin, zoomMax);
temp.y = Mathf.SmoothDamp (temp.y, zoom, ref velocity, smooth);
temp += new Vector3(Input.GetAxis("Horizontal") * scrollSpeed * Time.deltaTime,
0,
Input.GetAxis("Vertical") * scrollSpeed * Time.deltaTime);
// move the camera with moving mouse out of screen bounds
if (Input.mousePosition.x < ScrollArea)
temp += Vector3.right * -scrollSpeed * Time.deltaTime;
if (Input.mousePosition.x >= Screen.width - ScrollArea)
temp += Vector3.right * scrollSpeed * Time.deltaTime;
if (Input.mousePosition.y < ScrollArea)
temp += Vector3.forward * -scrollSpeed * Time.deltaTime;
if (Input.mousePosition.y > Screen.height - ScrollArea)
temp += Vector3.forward * scrollSpeed * Time.deltaTime;
transform.position = temp;
}
edit
Btw this is all untested but it should work ;)
Cheers for pointing that out! Just modified the code, and BAA$$anonymous$$ camera feels much more "direct" and faster, but in a good way, like still smooth but faster =) The only problem is, when restricting zoom with Clamp, it allows me to go even further than the zoom$$anonymous$$ax and then slowly lowers the camera..