Search Unity

Update position of active child when switching between children

Discussion in 'Scripting' started by superjeep3, Jul 18, 2017.

  1. superjeep3

    superjeep3

    Joined:
    Dec 1, 2012
    Posts:
    8
    Heya all, first...thank you for the views.

    Second, I followed a tutorial about switching weapons, and applied it to switching between characters. The three characters are children of an empty game object. What I am wanting to do is have the active child snap to the position of the previous active child so that after the currently active child moves, and then set to not active while another child is set to active...the currently active child will be in the same position that the previously active child was in...if that makes sense.

    I am trying to store the Vector3 of the currently active child, and then apply that Vector3 to whichever child is activated next, but I am not getting the results I thought I would. Here is what I have:



    Code (CSharp):
    1. public int selectedCharacter = 0;
    2.     private Vector3 currentPosition;
    3.  
    4.    // Use this for initialization
    5.    void Start ()
    6.     {
    7.         selectCharacter();
    8.     }
    9.  
    10.    // Update is called once per frame
    11.    void Update ()
    12.     {
    13.  
    14.         int previousSelectedCharacter = selectedCharacter;
    15.  
    16.        if (Input.GetAxis("Mouse ScrollWheel") > 0f || Input.GetButtonDown ("ScrollUp"))
    17.         {
    18.             if (selectedCharacter >= transform.childCount - 1)
    19.             {
    20.                 selectedCharacter = 0;
    21.             }
    22.             else selectedCharacter++;
    23.         }
    24.  
    25.         if (Input.GetAxis("Mouse ScrollWheel") < 0f || Input.GetButtonDown("ScrollDown"))
    26.         {
    27.             if (selectedCharacter <= 0)
    28.             {
    29.                 selectedCharacter = transform.childCount - 1;
    30.             }
    31.             else selectedCharacter--;
    32.         }
    33.  
    34.         if(previousSelectedCharacter != selectedCharacter)
    35.         {
    36.             selectCharacter();
    37.         }
    38.     }
    39.     void selectCharacter()
    40.     {
    41.         int i = 0;
    42.         foreach(Transform character in transform)
    43.         {
    44.             currentPosition = character.gameObject.transform.position;
    45.  
    46.             if (i == selectedCharacter)
    47.             {
    48.                 character.gameObject.transform.position = currentPosition;
    49.                 character.gameObject.SetActive(true);
    50.             }
    51.  
    52.             else
    53.                 character.gameObject.SetActive(false);
    54.                 i++;
    55.         }
    56.     }
    57.  
    58. }
    59.  
    Any help would be appreciated.
     
    Last edited: Jul 18, 2017
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
  3. superjeep3

    superjeep3

    Joined:
    Dec 1, 2012
    Posts:
    8
  4. superjeep3

    superjeep3

    Joined:
    Dec 1, 2012
    Posts:
    8
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Looking at this, I'm a little confused. It appears you only have one object active at a time and if you are always applying a position to the active gameobject that is the same as the previous object, then it will always be the same position. Can you better explain what you are trying to do?

    Because as it sits, if you only need stuff on and off and they are always going to be in the same spot, you can just put them there and turn them on and off.
     
  6. superjeep3

    superjeep3

    Joined:
    Dec 1, 2012
    Posts:
    8
    Sure...I will try to explain it better.

    I have three characters that are all children of an empty game object. The script (as it is) allows me to cycle through each character as I see fit. The idea is that each character would have different abilities, and would be utilized in different situations.

    I have a character controller script on each character (not the parent game object) so the control script does not move the parent game object. Because of this, the positions of the characters are different when they are enabled, or disabled. This also means that the characters appear to "pop" to different locations when you cycle through them.

    What I am trying to do is to store the gameObject.transform.position from the character that has just been disabled, and apply it to the gameObject.transform.position of the character as it is enabled. This way the characters will always be in the same position as the previous character, and will not appear to "pop" to other positions when enabled.

    In the simplest terms...I am wanting to store the position of the previous character, and apply it to the current character as you cycle through the characters.

    I hope that explained it better.
     
  7. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    That helped. I can't really show you a better solution at this moment, but I'll see what I can do later tonight.
     
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Untested, but this might give you want you want. Just populate the character array with your characters.

    Code (CSharp):
    1.     public GameObject[] chars;
    2.     int selectedChar = 0;
    3.  
    4.     void Update()
    5.     {
    6.         if (Input.GetAxis("Mouse ScrollWheel") > 0f || Input.GetButtonDown("ScrollUp"))
    7.         {
    8.             selectCharacter(1);
    9.         }
    10.         else if (Input.GetAxis("Mouse ScrollWheel") < 0f || Input.GetButtonDown("ScrollDown"))
    11.         {
    12.             selectCharacter(-1);
    13.         }
    14.     }
    15.  
    16.     void selectCharacter(int num)
    17.     {
    18.         Vector3 pos = chars[selectedChar].transform.position;
    19.         int newChar = 0;
    20.         if(selectedChar + num < 0)
    21.         {
    22.             newChar = chars.Length - 1;
    23.         }
    24.         else if(selectedChar + num > chars.Length -1)
    25.         {
    26.             newChar = 0;
    27.         }
    28.         else
    29.         {
    30.             newChar = selectedChar + num;
    31.         }
    32.  
    33.         chars[selectedChar].SetActive(false);
    34.         chars[newChar].transform.position = pos;
    35.         chars[newChar].SetActive(true);
    36.         selectedChar = newChar;
    37.     }
    38.  
     
  9. superjeep3

    superjeep3

    Joined:
    Dec 1, 2012
    Posts:
    8
    Awesome!!! Your code is much more compact than what I had, and it works for the most part...which not all of mine did. The one issue I saw was that all three characters were active at the beginning. You have to cycle through all three before only one would be active at a time. I tried calling the selectCharacter function with a num value of 0 (selectCharacter(0); ) in the Start function, but that did not work. I also added a Quaternion so that the rotation is also stored and applied to the active character. Thank you for the help.

    I think I will have to store the movement speed as the new character will often start in the idle pose and then transfer into the run animation instead of the new character already being in a run state if the previous character was running.
     
    Last edited: Jul 20, 2017
  10. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Yes, the thought is either you only have the first one active at the start(whatever is in slot 0), or you have to set one active at the start (if you wanted it to be random or to remember what the char last selected). This was mostly an example that you'll have to adapt for your needs as I don't know your games setup, so I can only give you the basics.

    You could also add your loop to start to turn off all chars that aren't the right matching index, but once that's done once, you really have no need to loop through them all again as you only have one char active at a time, so it's generally better to just turn off the old char and then turn on the new one.

    And yeah, if you have to, just add another variable to grab movement and set that along with position.

    Glad it's helping out!