Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by minefriek · Jun 03, 2014 at 09:13 AM · cameramovementrtsscrollingarrow-keys

Fixing Issues with custom RTS Camera Controll Script

Um Hello everyone, I've been working on a project for a while thats really close to my heart and has been a vision in my head for many years that's finally beginning to take shape for the first time. The problem is that one of the cameras wont work properly. When i use the edge scrolling or arrow keys I can only go down or to the left. The zoom doesnt work at all either. Its a custom script I created using the best parts of several other scripts so here it is below, I really could use some help here.

 using UnityEngine;
 using System.Collections;
 
 public class StrategyMovement : MonoBehaviour
 {    private const int ZoomSpeed = 50;
     private const int ZoomMin = 25;
     private const int ZoomMax = 100;
     private const int PanSpeed = 50;
     private const int PanAngleMin = 50;
     private const int PanAngleMax = 80;
 
     // Update is called once per frame
     void Update () {
     
     // Init camera translation for this frame.
     var translation = Vector3.zero;
     
     // Mouse Buttons and Edge Scrolling Stuff
     float mousePosX = Input.mousePosition.x; 
     float mousePosY = Input.mousePosition.y; 
     int scrollDistance = 5; 
     float scrollSpeed = 70;
     float ScrollAmount = scrollSpeed *Time.deltaTime;
         
     //mouse left
     if ((mousePosX < scrollDistance) && (transform.position.x > 500)) { 
         transform.Translate (-ScrollAmount,0,0, Space.World); 
     } 
     //mouse right
     if ((mousePosX >= Screen.width - scrollDistance) && (transform.position.x < 500)) { 
         transform.Translate (ScrollAmount,0,0, Space.World);  
     }
     //mouse down
     if ((mousePosY < scrollDistance) && (transform.position.z > 500)) { 
         transform.Translate (0,0,-ScrollAmount, Space.World); 
     } 
     //mouse up
     if ((mousePosY >= Screen.height - scrollDistance) && (transform.position.z < 500)) { 
         transform.Translate (0,0,ScrollAmount, Space.World); ; 
     }
     //Keyboard controls 
     if ((Input.GetKey(KeyCode.UpArrow)) && (transform.position.z < -500)) { 
         transform.Translate (0,0,ScrollAmount, Space.World); ; 
     } 
     if ((Input.GetKey(KeyCode.DownArrow)) && (transform.position.z > 500)) { 
         transform.Translate (0,0,-ScrollAmount, Space.World);
     }
     if ((Input.GetKey(KeyCode.LeftArrow)) && (transform.position.x > 500)) { 
         transform.Translate (-ScrollAmount,0,0, Space.World);  
     } 
     if ((Input.GetKey(KeyCode.RightArrow)) && (transform.position.x < -500)) { 
         transform.Translate (ScrollAmount,0,0, Space.World); 
     }
     
     // Zoom in or out
     var zoomDelta = Input.GetAxis("Mouse ScrollWheel")*ZoomSpeed*Time.deltaTime;
         if (zoomDelta!=0){
             translation -= Vector3.up * ZoomSpeed * zoomDelta;
         }
         
     // Start panning camera if zooming in close to the ground or if just zooming out.
     var pan = camera.transform.eulerAngles.x - zoomDelta * PanSpeed;
         pan = Mathf.Clamp(pan, PanAngleMin, PanAngleMax);
         
     if (zoomDelta < 0 || camera.transform.position.y < (ZoomMax / 2)){
         camera.transform.eulerAngles = new Vector3(pan, 0, 0);
     }
 }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Zodiarc · Jun 03, 2014 at 10:30 AM

I don't really see why the code would not work, but I can show you how I did something similar (but for a TBS game).

 #pragma strict
 
 class CameraControls extends MonoBehaviour{
     
     public var speed: float = 5.0f;
     public var terrain: GameObject;
     public var xRotator: GameObject;
     private var terrainHeight:float;
     private var t:float = 0.0f;
     private var mouseClickPosition:Vector2;
     
     private function moveRight():void{
         if(Input.mousePosition.x > Screen.width * 0.95f || Input.GetKey(KeyCode.RightArrow)){
             this.transform.Translate(Vector3.right * this.speed * Time.deltaTime);
             this.getTerrainHeight();
         }
     }
     
     private function moveLeft():void{
         if(Input.mousePosition.x < Screen.width * 0.05f || Input.GetKey(KeyCode.LeftArrow)){
             this.transform.Translate(-Vector3.right * this.speed * Time.deltaTime);
             this.getTerrainHeight();
         }
     }
     
     private function moveForward():void{
         if(Input.mousePosition.y < Screen.height * 0.05f || Input.GetKey(KeyCode.DownArrow)){
             this.transform.Translate(-Vector3.forward * this.speed * Time.deltaTime);
             this.getTerrainHeight();
         }
     }
     
     private function moveBackward():void{
         if(Input.mousePosition.y > Screen.height * 0.95f || Input.GetKey(KeyCode.UpArrow)){
             this.transform.Translate(Vector3.forward * this.speed * Time.deltaTime);
             this.getTerrainHeight();
         }
     }
     
     private function getTerrainHeight(){
         var hit: RaycastHit;
         this.terrain.layer = 0;
         // Get terrain y value at current position.
         if(Physics.Raycast(Vector3(this.transform.position.x, 300, this.transform.position.z), -Vector3.up, hit, 500)){
             this.terrainHeight = hit.point.y;
         }
         this.terrain.layer = 2;
     }
     
     private function adjustToTerrainHeight(){
         if(this.transform.position.y != this.terrainHeight){
             this.transform.position.y = Mathf.Lerp(this.transform.position.y, this.terrainHeight, this.t);
             //this.transform.position.y = this.terrainHeight;
             Debug.Log("y " + this.terrainHeight);
             t += Time.deltaTime;
         }
         else{
             this.t = 0;
         }
     }
     
     private function rotateCamera():void{
         if(Input.GetMouseButtonDown(1)){
                 this.mouseClickPosition = Input.mousePosition;
         }
         if(Input.GetMouseButton(1)){
             var delta = this.mouseClickPosition - Input.mousePosition;
             this.mouseClickPosition = Input.mousePosition;
             this.transform.Rotate(Vector3.up * -this.speed * delta.x * Time.deltaTime);
             this.xRotator.transform.Rotate(Vector3.right * this.speed * delta.y * Time.deltaTime);
             this.xRotator.transform.rotation.eulerAngles.x = ClampAngle(this.xRotator.transform.rotation.eulerAngles.x, 0.0f, 40.0f);
         }
     }
     
     private function ClampAngle(angle: float, min: float, max: float): float {
         if (angle<90 || angle>270){       // if angle in the critic region...
             if (angle>180) angle -= 360;  // convert all angles to -180..+180
             if (max>180) max -= 360;
             if (min>180) min -= 360;
         }   
         angle = Mathf.Clamp(angle, min, max);
         if (angle<0) angle += 360;  // if angle negative, convert to 0..360
         return angle;
     }
     
     public function Update(){
         if(!Input.GetMouseButton(1)){
             this.moveRight();
             this.moveLeft();
             this.moveForward();
             this.moveBackward();
         }
         if(Input.GetKeyDown(KeyCode.Escape)){
             Application.Quit();
         }
     }
     
     public function LateUpdate(){
         this.adjustToTerrainHeight();
         this.rotateCamera();
     }
 }

The camera setup is like this (as tree):

Camera Setup

You won't probably need the terrain. I need it to switch its layers dynamically because I don't want my grid to hit it with raycasts to determine the moving radius with built-in obstacle detection.

The script is attached to the yRotator.

For the zooming I would do it in a separate script, use Translate(Vector3.forward speed Time.deltaTime) and attach it to the main camera (in the setup i showed you here) or add another public variable for the main camera. Speed should of course be negative or positive depending on the scroll direction.

Maybe you can get some inspiration from it.

C# version (no guarantee for correctness)

 using UnityEngine;
 using System.Collections;
  
 public class CameraControls : MonoBehaviour{
  
     public float speed = 5.0f;
     public GameObject terrain;
     public GameObject xRotator;
     private float terrainHeight;
     private float t = 0.0f;
     private Vector2 mouseClickPosition;
  
     private void moveRight(){
        if(Input.mousePosition.x > Screen.width * 0.95f || Input.GetKey(KeyCode.RightArrow)){
          this.transform.Translate(Vector3.right * this.speed * Time.deltaTime);
          this.getTerrainHeight();
        }
     }
  
     private void moveLeft(){
        if(Input.mousePosition.x < Screen.width * 0.05f || Input.GetKey(KeyCode.LeftArrow)){
          this.transform.Translate(-Vector3.right * this.speed * Time.deltaTime);
          this.getTerrainHeight();
        }
     }
  
     private void moveForward(){
        if(Input.mousePosition.y < Screen.height * 0.05f || Input.GetKey(KeyCode.DownArrow)){
          this.transform.Translate(-Vector3.forward * this.speed * Time.deltaTime);
          this.getTerrainHeight();
        }
     }
  
     private void moveBackward(){
        if(Input.mousePosition.y > Screen.height * 0.95f || Input.GetKey(KeyCode.UpArrow)){
          this.transform.Translate(Vector3.forward * this.speed * Time.deltaTime);
          this.getTerrainHeight();
        }
     }
  
     private void getTerrainHeight(){
        RaycastHit hit;
        this.terrain.layer = 0;
        // Get terrain y value at current position.
        if(Physics.Raycast(Vector3(this.transform.position.x, 300, this.transform.position.z), -Vector3.up, hit, 500)){
          this.terrainHeight = hit.point.y;
        }
        this.terrain.layer = 2;
     }
  
     private void adjustToTerrainHeight(){
        if(this.transform.position.y != this.terrainHeight){
          this.transform.position.y = Mathf.Lerp(this.transform.position.y, this.terrainHeight, this.t);
          //this.transform.position.y = this.terrainHeight;
          Debug.Log("y " + this.terrainHeight);
          t += Time.deltaTime;
        }
        else{
          this.t = 0;
        }
     }
  
     private void rotateCamera():void{
        if(Input.GetMouseButtonDown(1)){
           this.mouseClickPosition = Input.mousePosition;
        }
        if(Input.GetMouseButton(1)){
          Vector2 delta = this.mouseClickPosition - Input.mousePosition;
          this.mouseClickPosition = Input.mousePosition;
          this.transform.Rotate(Vector3.up * -this.speed * delta.x * Time.deltaTime);
          this.xRotator.transform.Rotate(Vector3.right * this.speed * delta.y * Time.deltaTime);
          this.xRotator.transform.rotation.eulerAngles.x = ClampAngle(this.xRotator.transform.rotation.eulerAngles.x, 0.0f, 40.0f);
        }
     }
  
     private float ClampAngle(float angle, float min, float max) {
         if (angle<90 || angle>270){       // if angle in the critic region...
             if (angle>180) angle -= 360;  // convert all angles to -180..+180
             if (max>180) max -= 360;
             if (min>180) min -= 360;
         }   
         angle = Mathf.Clamp(angle, min, max);
         if (angle<0) angle += 360;  // if angle negative, convert to 0..360
         return angle;
     }
  
     public void Update(){
        if(!Input.GetMouseButton(1)){
          this.moveRight();
          this.moveLeft();
          this.moveForward();
          this.moveBackward();
        }
        if(Input.GetKeyDown(KeyCode.Escape)){
          Application.Quit();
        }
     }
  
     public void LateUpdate(){
        this.adjustToTerrainHeight();
        this.rotateCamera();
     }
 }

tree.png (11.7 kB)
Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image minefriek · Jun 03, 2014 at 11:19 AM 0
Share

Thanks for the answer, im going to try out your way and see where it takes me, though could I please have a variation of this in C#?

avatar image Zodiarc · Jun 03, 2014 at 11:23 AM 0
Share

Unfortunately I'm not an expert in C# but I can try to translate it.

EDIT: I translated it, but I'm unable to say if it will work from scratch. $$anonymous$$aybe you will have to remove some syntax errors.

You are also free to mess around with the values in all functions to adjust them to your needs but don't touch ClampAngle() because it will ruin the rotation on the x axis (but you can change the paramteres passed to the function).

avatar image minefriek · Jun 03, 2014 at 11:51 AM 0
Share

Thankyou so much for your help, I now have enough examples of working code to update my script and get everything to work properly

avatar image minefriek · Jun 03, 2014 at 12:04 PM 1
Share

works really well, few small problems but once i removed the terrain checkers and the raycast it worked pretty well, thankyou :D

avatar image meat5000 ♦ · Jun 03, 2014 at 12:52 PM 1
Share

You should show your appreciation with some thumbs up :)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

RTS Mouse Click Movement 1 Answer

3D RTS camera 3 Answers

Attaching an RTS scrolling script to a camera (Noob Question) 3 Answers

Move Camera According to Mouse Movement While Button is Pressed 1 Answer

Unity3d RTS style camera movement is jittery 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges