Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Two objects sharing the same class

Discussion in 'Scripting' started by jensmcatanho, Dec 24, 2014.

  1. jensmcatanho

    jensmcatanho

    Joined:
    Jul 11, 2014
    Posts:
    21
    Hello, guys.

    I'm having a few problems in game because I have two players which share the class PlayerSetup and there are some variables that are individual for each player (e.g. velocity). When it's player one's turn and he changes his velocity from x to y, player two's velocity also changes to y.

    I want to know how can I manipulate both velocitys as different things although the two objects have the same class.
     
  2. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Public variables are exclusive to each instance of the class.

    So if your class looks like:

    Code (csharp):
    1.  
    2. public class PlayerSetup : MonoBehaviour
    3. {
    4.     public Vector3 velocity;
    5. }
    6.  
    Then modifying velocity on one player, will not change the other. You can make them share a variable by declaring it static:

    Code (csharp):
    1.  
    2. public class PlayerSetup : MonoBehaviour
    3. {
    4.     public static List<PlayerSetup> players = new List<PlayerSetup>();
    5.    
    6.     public Vector3 velocity;
    7.    
    8.     void OnEnable()
    9.     {
    10.         players.Add(this);
    11.     }
    12.     void OnDisable()
    13.     {
    14.         players.Remove(this);
    15.     }
    16. }
    17.  
     
  3. jensmcatanho

    jensmcatanho

    Joined:
    Jul 11, 2014
    Posts:
    21
    My code looks like the first one, but let's say I want to do something like this on PlayerSetup:

    Code (CSharp):
    1.  
    2.     void Update () {
    3.         if (Input.GetKey(KeyCode.D)) {
    4.             velocity += 1.0f;
    5.         }
    6.  
    7.         if (Input.GetKey(KeyCode.A)) {
    8.             velocity -= 1.0f;
    9.  
    10.             if (velocity < 1.0f)
    11.                 velocity = 1f;
    12.         }
    13.     }
    Both players have the PlayerSetup class in the same scene but when the player types "D" or "A", how can I define which velocity will increase (or decrease)? The way I did changed both velocities.

    I imagined a conditions statement like "if it's player one's turn, change his velocity and his velocity only" but I don't know how is it possible to do this without changing player two's velocity too.
     
  4. cranky

    cranky

    Joined:
    Jun 11, 2014
    Posts:
    180
    You need logic in there that reads like: If my turn, proceed. Else do nothing. What is happening is both objects are calling Input.GetKey in their update method, and each object is increasing its own velocity because the key is down. You only want that code to be run whenever it's that player's turn. You need an additional script that manages whose turn it is. Make a public bool "isMyTurn" in your player class and have the new script manage that value. Then at the beginning of your player Update() function, add "if (!isMyTurn) return;"
     
  5. jensmcatanho

    jensmcatanho

    Joined:
    Jul 11, 2014
    Posts:
    21
    I was using that logic to define which turn is it but when I change the velocity on player one's turn, the velocity is changed when player two's turn starts.
     
  6. jensmcatanho

    jensmcatanho

    Joined:
    Jul 11, 2014
    Posts:
    21
    I discovered after some tests that it works with this line of code but is it the best way to access that instance of the class each time I need?

    Code (CSharp):
    1. GameObject.FindGameObjectWithTag("Player 1").GetComponent<PlayerSetup>().velocity
    For exemple, the code I posted above would look like something like this:

    Code (CSharp):
    1.     void Update () {
    2.         if (Input.GetKey(KeyCode.D)) {
    3.             GameObject.FindGameObjectWithTag("Player 1").GetComponent<PlayerSetup>().velocity += 1.0f;
    4.         }
    5.         if (Input.GetKey(KeyCode.A)) {
    6.             GameObject.FindGameObjectWithTag("Player 1").GetComponent<PlayerSetup>().velocity -= 1.0f;
    7.             if (GameObject.FindGameObjectWithTag("Player 1").GetComponent<PlayerSetup>().velocity < 1.0f)
    8.                 GameObject.FindGameObjectWithTag("Player 1").GetComponent<PlayerSetup>().velocity = 1f;
    9.         }
    10.     }
    It looks kind of silly to me, is there a better way of doing this?
     
  7. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    489
    You could do it with a variable

    Code (CSharp):
    1.  
    2. public PlayerSetup referencePlayer; //Allows you to assign a player in the inspector
    3.  
    4. void Start(){
    5. referencePlayer.velocity = Vector3.zero;
    6. }
    7.  
     
  8. jensmcatanho

    jensmcatanho

    Joined:
    Jul 11, 2014
    Posts:
    21
    Thanks, aaro4130. It worked just as I wanted! :)
     
    ZO5KmUG6R likes this.