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
1
Question by animalphase · May 17, 2013 at 11:05 PM · switch characters

Switching between first-person Character Controllers

I have a scene with multiple Character Controllers, all first-person. They are all based on the same Character Controller, but each one hase different children with different scripts attached. (One carries a flashlight and has a HUD, another cannot move, etc). I need to:

  1. Activate the correct Character Controller at the start of the scene (and deactivate the rest).

  2. At triggered moments, swap to another Character Controller.

There are many similar questions here in unityAnswers, but I am having a hard time coming up with a solution that caters to this specific circumstance. One idea seems to be:

Find all scripts attached to Character Controllers + all children and disable all. Disable cameras. Then, enable all scripts on the desired character controller plus its camera.

However, I do no know how to find all scripts in all children, so I haven't been able to test this yet.

Thank you.

Comment
Add comment · Show 1
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 animalphase · May 17, 2013 at 11:07 PM 0
Share

I started a snippet of code for initialization that might be on the right track. I set up an array to hold references to all character controllers, and playerControllerList[0] will be the starting character. This codes runs on game start:

 public GameObject[] playerControllerList;
     
 void Start () {
     for( int i = 1; i < playerControllerList.Length; i++ ){
             playerControllerList[i].GetComponent<$$anonymous$$onoBehaviour>().enabled = false;
     }
 }

However, the actual .enabled = false; does not work. Supposedly this .enabled = false line needs to be applied to all scripts attached to all children.

1 Reply

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

Answer by aldonaletto · May 17, 2013 at 11:32 PM

Just disabling the scripts may not be enough: a disabled script still can process events like OnTriggerEnter, OnCollisionEnter etc. A better and simpler alternative would be to deactivate all game objects except the one currently selected - for instance:

 public int curPlayer = 0;
 public GameObject[] playerControllerList;
 
 void Start () {
     for( int i = 0; i < playerControllerList.Length; i++ ){
         // activate only curPlayer, and deactivate the others:
         playerControllerList[i].SetActive(i == curPlayer);
     }
 } 

EDITED:

The alternative above is ideal for cases where only a single player may exist at any time. If the other players must stay alive but simply don't answer to commands, maybe the script disabling approach is better. A reasonably way to do that is to keep in each player an enabling script: this script gets at Start an array of all scripts attached to the player instance (including itself), and enable/disable them with a dedicated function. You should then have an empty object with the players list and the selection function, which should call the enabling function in all players when selecting one of them.

The enabling script:

 using UnityEngine;
 using System.Collections;
 
 public class EnablePlayer: MonoBehaviour {
 
   MonoBehaviour[] scripts; // list of all scripts in this player
 
   void Start(){ // get the scripts list at Start:
     scripts = GetComponentsInChildren<MonoBehaviour>();
   }

   // enabling function:
   public void EnableMe(bool onOff){
     foreach (MonoBehaviour script in scripts){
       script.enabled = onOff;
     }
   }

 }

The control script:

 using UnityEngine;
 using System.Collections;
 
 public class SelectPlayer: MonoBehaviour {

   public EnablePlayer[] playerList; // drag the players here
 
   void SelPlayer(int whichOne) {
     for( int i = 0; i < playerList.Length; i++ ){
       // activate only whichOne, and deactivate the others:
       playerList[i].EnableMe(i == whichOne);
     }
   } 

 }

Disabling a script makes Unity stop calling its Update, FixedUpdate and LateUpdate functions - but the script still exists, so you can directly call any function, read/write its variables etc. This is good, but may be bad too: if an enemy is shooting at the player, for instance, it will keep hurting the unlucky guy even after you've switched to another player. If you want to avoid this, use the enabled script property to "disable" any function that you don't want to be executed when the player isn't selected - for instance:

 public void SomeFunctionThatMustAlsoBeDisabled(){
   // abort this function when the script is disabled:
   if (!enabled) return; 
   ... 
 }
Comment
Add comment · Show 3 · 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 animalphase · May 17, 2013 at 11:58 PM 0
Share

Thank you, this is perfect! the "SetActive" function is exactly what I was missing. I also never thought do a Boolean comparison with an object flag, so thanks for the other tip!

The one downside is that the other Controllers, renderer and all, will be disabled. However, it does not affect me, as in this project, none of the character will be able to see each other anyway.

Once I get the entire system working, I will edit my original post for anyone that my stumble across this question in the future.

avatar image aldonaletto · May 18, 2013 at 05:34 AM 1
Share

Anyway, I included a script disabling alternative in my answer - from your comment above, this approach may be better for your game. It's a little slower, but this may make no difference at all since players aren't supposed to be switched very often.

avatar image animalphase · May 18, 2013 at 08:13 AM 0
Share

Nice, thank you for the extra information in the edit. I have a prototype working with the initial SetActive() method, but I plan to update to this new script-disabling method.

I do not actually need to see the other Character Controllers, though keeping them all active but with disabled scripts will be nice - sometimes a character swap may happen while the player is falling through the air, and this approach will allow the Character controller to naturally come to rest on the ground even as the player is controlling another character controller.

Very clever coding. GetComponentsInChildren() is something else that I was missing out on - I am definitely learning a lot.

For the moment, I have my code set up with a an extra layer of functions to swap the player, for example:

 void setController0() {
     helmetCamera.SetActive(true);
     currentController = 0;
     setController();
 }

 void setController1() {
     helmetCamera.SetActive(false);
     currentController = 1;
     setController();
 }
 
 void setController() {
     for( int i = 0; i < playerControllerList.Length; i++ ){
         playerControllerList[i].SetActive(i == currentController);
     }
 }

This allows me to put in extra toggles and actions in the initial "setControllerX" function (like enabling or disabling the "helmetCamera" as above, etc). However, with your script, I will be able to put these Character-specific toggles within Controller's Enable$$anonymous$$e() function, and have each on/off property controlled by Boolean variables within each Controller.

Your solution may prove to be more useful, as each Controller's options could be easily ticked on and off in the inspector.

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

14 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

Related Questions

Switching from GameObject to GameObject by using a list 1 Answer

Changing player model with keypress. 3 Answers

Switch turns between the Player and AI 0 Answers

View and control script broken? 1 Answer

Need help with fixing a code 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