- Home /
RTS Style Camera Scrolling
I've decided to make a RTS (real time strategy) game. I have a camera set up at the angle I want, and everything is coming along fine. However, I need some method of moving the camera. I suppose I could use the arrow keys, but I'd really rather not. So, deciding to make a camera scroll where you simply move the mouse to the edge of the screen and have the camera scroll in that direction, I started looking around in order to locate something that could help me out. I spent about three hours surfing, and came up with... nothing! So, I thought I'd just ask another question for everybody that's already given up in despair. How would you implement such a feature?
Thanks in advance - Elliot Bonneville
I know this is an old thread but I found it very useful and it still works! Thanks
Answer by Eric5h5 · Mar 21, 2010 at 04:13 AM
The Update function in the editor script in this example project has code for scrolling. Including the edge of the screen method, arrow keys, and middle mouse button method; pretty much all the RTS games I've played have at least the first two. Not including the public variables for scrolling speed and so on, the relevant code is:
var mPosX = Input.mousePosition.x; var mPosY = Input.mousePosition.y;
// Do camera movement by mouse position if (mPosX < scrollArea) {myTransform.Translate(Vector3.right -scrollSpeed Time.deltaTime);} if (mPosX >= Screen.width-scrollArea) {myTransform.Translate(Vector3.right scrollSpeed Time.deltaTime);} if (mPosY < scrollArea) {myTransform.Translate(Vector3.up -scrollSpeed Time.deltaTime);} if (mPosY >= Screen.height-scrollArea) {myTransform.Translate(Vector3.up scrollSpeed Time.deltaTime);}
// Do camera movement by keyboard myTransform.Translate(Vector3(Input.GetAxis("EditorHorizontal") scrollSpeed Time.deltaTime, Input.GetAxis("EditorVertical") scrollSpeed Time.deltaTime, 0) );
// Do camera movement by holding down option or middle mouse button and then moving mouse if ( (Input.GetKey("left alt") || Input.GetKey("right alt")) || Input.GetMouseButton(2) ) { myTransform.Translate(-Vector3(Input.GetAxis("Mouse X")*dragSpeed, Input.GetAxis("Mouse Y")*dragSpeed, 0) ); }
Wow! I'm impressed... It worked almost right off the bat. Thanks, Eric!
One problem however. Don't know if I want to post this as a new question, but my cam is rotated, and when I go forward or backwards, it goes up slightly, because the rotation is pointing up. I was looking around for a 'lock translation' option, but I thought I'd just ask because your answer was so useful.
Never$$anonymous$$d, I got it. Slightly unorthodox solution of placing a collider above and below the camera. Bit jerky every now and then, but it works. Better solution, though, = happy me.
@elbon96: try adding Space.World to the Translate function.
The scrollArea variable is a integer (int). It describes how close the mouse must be to the edge of the screen for the camera to scroll (in pixels).
Answer by feillyne · Mar 07, 2012 at 12:14 PM
Modified, working example of above code:
var mousePosX = Input.mousePosition.x; var mousePosY = Input.mousePosition.y; var scrollDistance : int = 5; var scrollSpeed : float = 70;
if (mousePosX < scrollDistance) { transform.Translate(Vector3.right -scrollSpeed Time.deltaTime); } if (mousePosX >= Screen.width - scrollDistance) { transform.Translate(Vector3.right scrollSpeed Time.deltaTime); }
if (mousePosY < scrollDistance) { transform.Translate(Vector3.up -scrollSpeed Time.deltaTime); } if (mousePosY >= Screen.height - scrollDistance) { transform.Translate(Vector3.u) scrollSpeed Time.deltaTime); },var mousePosX = Input.mousePosition.x; var mousePosY = Input.mousePosition.y; var scrollDistance : int = 5; var scrollSpeed : float = 70;
if (mousePosX < scrollDistance) { transform.Translate(Vector3.right -scrollSpeed Time.deltaTime); } if (mousePosX >= Screen.width - scrollDistance) { transform.Translate(Vector3.right scrollSpeed Time.deltaTime); }
if (mousePosY < scrollDistance) { transform.Translate(Vector3.up -scrollSpeed Time.deltaTime); } if (mousePosY >= Screen.height - scrollDistance) { transform.Translate(Vector3.up scrollSpeed Time.deltaTime); }
Answer by Aggressor · Apr 30, 2012 at 08:21 PM
Thanks Feilyne (though you pasted the code twice in a row).
I am doing an iso metric RTS game (with C#). Because of this the Z axis was moving through the terrain (rather than scrolling up).
So to address this I created an empty game object (which was aligned with the terrain). Attached the camera movement script to it, and then nested the main camera inside the empty object.
Also here is the C# code I used (modified from Feilynes)
using UnityEngine; using System.Collections;
public class CameraController : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float mousePosX = Input.mousePosition.x;
float mousePosY = Input.mousePosition.y;
int scrollDistance = 5;
float scrollSpeed = 70;
if (mousePosX < scrollDistance)
{
transform.Translate(Vector3.right * -scrollSpeed * Time.deltaTime);
}
if (mousePosX >= Screen.width - scrollDistance)
{
transform.Translate(Vector3.right * scrollSpeed * Time.deltaTime);
}
if (mousePosY < scrollDistance)
{
transform.Translate(transform.forward * -scrollSpeed * Time.deltaTime);
}
if (mousePosY >= Screen.height - scrollDistance)
{
transform.Translate(transform.forward * scrollSpeed * Time.deltaTime);
}
}
}
@Darker It's the position of the object associated with the script (here it'll be the camera).
Answer by JDB-Artist · Nov 17, 2012 at 08:54 PM
Many thanks for the solution! Could you give me an advise how to include a smoothing method in the camera scrolling? I think that the scrolling effect is a little abrupt/sudden and if possible I would like to smooth/fade in & out the camera movement.
I think you should look up into SmoothDamp if you want smoothness.. http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.SmoothDamp.html
Answer by samsmithnz · Dec 27, 2012 at 10:17 PM
How do I limit mouse movements so that the user can't scroll too far away from my scene? With the keyboard I was able to use the following code, but I can't seem to find the equivalent with the mouse.
private float leftSide = -100f; private float rightSide = -80f; private float topSide = -80f; private float bottomSide = -100f; // Update is called once per frame void Update () { ///////////////////// //keyboard scrolling float translationX = Input.GetAxis("Horizontal"); float translationZ = Input.GetAxis("Vertical"); float toX = translationX + translationZ; if (transform.position.x + toX < leftSide) { toX = 0; } if (transform.position.x + toX > rightSide) { toX = 0; } float toZ = translationZ - translationX; if (transform.position.z + toZ > topSide) { toZ = 0; } if (transform.position.z + toZ < bottomSide) { toZ = 0; } transform.Translate(toX, 0, toZ); //////////////////// //mouse scrolling float mousePosX = Input.mousePosition.x; float mousePosY = Input.mousePosition.y; int scrollDistance = 1; float scrollSpeed = 70; //Horizontal camera movement //horizontal, left if (mousePosX < scrollDistance) { transform.Translate(-1, 0, 1); } //horizontal, right if (mousePosX >= Screen.width - scrollDistance) { transform.Translate(1, 0, -1); } //Vertical camera movement //scrolling down if (mousePosY < scrollDistance) { transform.Translate(-1, 0, -1); } //scrolling up if (mousePosY >= Screen.height - scrollDistance) { transform.Translate(1, 0, 1); } }