Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by Nimwe · Apr 16, 2018 at 06:50 PM · cameraenabledswitch cameras

Designing a system to switch between cameras without disabling any of them

Greetings,

I'm currently trying to get a system of 5 cameras through which I can cycle by choosing the one I want to look at through keyboard inputs (AlphaKey 1 to 5). The layout I want to obtain is depicted in the screenshot alt text

But I cannot get my script to work (and I'm kind of ashamed by how ugly it looks) - the editor crashes when I test it and then press any key from 1 to 5. Here's what I've done so far, I apologize for the poor polishing and... everything else.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class MasterController : MonoBehaviour {
     public Camera[] camerasArray;
     public int selectedNum = 1, length;
     private void OnEnable()
     {
         InitializeCamerasArray(); //initialize cameras before startup
         length = camerasArray.Length;
     }
 
     private void Update()
     {
         //change the camera if the input is given
         if (AssignNum())
         {
             StartCoroutine(SwitchCamera()); 
         }
         
 
 
     }
 
     private void InitializeCamerasArray() //inserts the cameras in the array
     {
         camerasArray = Camera.allCameras;
         
     }
     private bool AssignNum() //changes the camera number to the correspondent pressed key
     {
         if (!Input.anyKeyDown)
         {
             return false;
         } else
         if (Input.GetKey("1"))
         {
             selectedNum = 1;
             return true;
         } else
         if (Input.GetKey("2"))
         {
             selectedNum = 2;
             return true;
         } else
         if (Input.GetKey("3"))
         {
             selectedNum = 3;
             return true;
         } else
         if (Input.GetKey("4"))
         {
             selectedNum = 4;
             return true;
         } else
         if (Input.GetKey("5"))
         {
             selectedNum = 5;
             return true;
         }
         return false;
     }
     IEnumerator SwitchCamera() //switch to the camera selected by attribute
     {
         int i = 0;
         while (i < length)
         {
             if ((i + 1) != selectedNum)
             {
                 BackGroundRect(i, camerasArray[i].rect);
                 i++;
             }
         }
         ForeGroundRect(camerasArray[selectedNum - 1].rect);
         yield return new WaitForSeconds(2);
     }
     private void BackGroundRect(int _i, Rect _r)
     {
         float x = (1 / (length - 1)) * _i;
         float y = 0;
         float w = (1 / (length - 1)) - 0.05f / length;
         float h = (1 / (length - 1)) - 0.05f / length;
         _r = new Rect(x, y, w, h);
     }
     private void ForeGroundRect(Rect _r)
     {
         float x = (1 - 1 / (length - 1)) / 2;
         float y = 1 / (length - 1);
         float w = 1 - 1 / (length - 1);
         float h = 1 - 1 / (length - 1);
         _r = new Rect(x, y, w, h);
     }
 }
 

Everything works but the part where SwitchCamera() starts. The idea is that I put all the non-selected cameras in the lower row, then put the selected one in the foreground. To do this I change each camera's rect to a new one, calculated based on the number of cameras I have (this is done with the intention to eventually put in a variable number of cameras, to do which I will also need to modify the AssignNum() method). Here the editor crashes, and I have no clue about why this happens.

If anyone's got a better way to achieve what I need I'm open to suggestions, but I would also really want to understand why my editor crashes.

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

4 Replies

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

Answer by Bunny83 · Apr 17, 2018 at 03:46 AM

Ohh man this is a huge collection of issues. First the reason for your hang (which btw is not a crash): In your while loop you only increase "i" inside your if statement body. That means the moment the loop hits the selected camera you will no longer enter the if statement and therefore i is no longer incremented and you're stuck in the while loop. This is a typical case for a "for" loop. The for loop has the advantage that the increment is unconditionally in the header.


Your two methods (BackGroundRect and ForeGroundRect) are pointless the way you designed the signatures. Rect is a struct. Structs are value types and therefore the method gets a copy of the struct. Changing the local copy inside the method won't change the Rect that was passed to the method. You should let the method return the Rect and assign it to the desired camera.


Inside your two methods you perform an integer division which would be rounded down to 0. If the operands of a division are both integers the result will be an integer as well. However "1 / 4" will be "0". That means all your calculated offsets and sizes are wrong. At least one operand has to be a float value in order to do a floating point division. Just use "1f" instead of "1".


As others have said there's no reason why your SwitchCamera method should be a coroutine. Any yield at the end of a coroutine is pointless since nothing else happens after the yield.


You really shouldn't use a 1 based system for storing the active camera. Just use a zero based value it makes all calculations and comparisons easier. So it reduces the chance for errors.

Comment
Add comment · 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
1

Answer by melsy · Apr 17, 2018 at 02:49 AM

First thing I notice is that the coroutine is allowed to stack multiple instances on itself. If the number key is held for more than one frame then the bool return true for that amount of frames. This will stack the coroutine and cause it to run several times .

Instead of a bool for key pressed make an int to get the index and send that to a check inside the coroutine for the array. then at the end of the coroutine change the bool back to false.

 // All pseudo code so dont copy paste 
 bool keydown;
 if(Input.GetKeyDown(Keycode.Alpha1))
 {
 keydown = true;
 // run the coroutine
 }

 int AssignNum()
 {
 
 // All the GetKeyDown(KeyCode.// Reference here
 // keyDown = true;
 // return Keycode int
 // Rest of the GetKeyDowns with the keycodes
 // then set keyDown to true;
 // then return the int number
 } 
  IEnumerator CoroutineCo()
 {
 //Stuff
 array[AssignNum()].rect;
 // WaitForSeconds
 // keyDown = false;
 }

I would do this with renderTextures and a plane image. That will give you a camera that can change its own perimeters based on the render texture and you can do what you are wanting to pretty easy. But it is very resource heavy.

Comment
Add comment · 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
1

Answer by MarioSantoso · Apr 17, 2018 at 03:02 AM

I don't know why you need coroutine here. Anyway, apply this script to any game object and you are good to go.

I made this script based on your needs for 5 cameras. This will fail if there is less or more camera. So make adjustment if you need to.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class MultipleCameras : MonoBehaviour
 {
     public Camera[] cameras;
 
     private Rect _foreRect;
     private Rect[] _backRect;
 
     private int _activeID;
 
     void Start()
     {
         InitializeCameras();
     }
 
     private void InitializeCameras()
     {
         cameras = Camera.allCameras;
 
         // Define all cameras' rect
         _foreRect = new Rect(0, 0.21f, 1, 1);
         _backRect = new Rect[]
         {
             new Rect(       0,      0,      0.245f,      0.2f),
             new Rect(   0.25f,      0,      0.245f,      0.2f),
             new Rect(   0.50f,      0,      0.245f,      0.2f),
             new Rect(   0.75f,      0,      0.25f,      0.2f)
         };
 
         // Reference to active camera ID
         _activeID = 0;
 
         // Assign rects to cameras
         cameras[0].rect = _foreRect;
         for (int i = 1; i < cameras.Length; i++)
             cameras[i].rect = _backRect[i - 1];
     }
 
     void Update()
     {
         // Detect user inputs
         if (Input.GetKeyUp(KeyCode.Alpha1))
             FocusOnCamera(0);
         else if (Input.GetKeyUp(KeyCode.Alpha2))
             FocusOnCamera(1);
         else if (Input.GetKeyUp(KeyCode.Alpha3))
             FocusOnCamera(2);
         else if (Input.GetKeyUp(KeyCode.Alpha4))
             FocusOnCamera(3);
         else if (Input.GetKeyUp(KeyCode.Alpha5))
             FocusOnCamera(4);
     }
 
     private void FocusOnCamera(int id)
     {
         // Swith the camera
         if (id == _activeID)
             return;
 
         cameras[_activeID].rect = cameras[id].rect;
         cameras[id].rect = _foreRect;
 
         _activeID = id;
     }
 }
 
Comment
Add comment · 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
0

Answer by OliverJackman · Sep 20, 2019 at 06:04 PM

it's super easy! just disable camera component on it ...

Comment
Add comment · 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

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

129 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 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 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 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 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 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

camera switch script works? 1 Answer

NullReferenceException: Object reference not set to an instance of an object 0 Answers

InputKey on Update with INT Counter - Camera Switch - Not working properly. 1 Answer

Camera Unet Problem 0 Answers

CRT Shader how optimize?! 1 Answer


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