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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Persist GameObject information across all scripts

Discussion in 'Scripting' started by skinner92, Aug 6, 2014.

  1. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    [SOLVED]
    Hello everyone. A long time has passed since my last post, and here we are again.

    Let me explain you my issue. I am creating a 2D shooter game (on top view). I created a class, SurvivorClass, that looks like this:

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. namespace AssemblyCSharp
    5. {
    6.     public class SurvivorClass
    7.     {
    8.         private WeaponClass weapon;
    9.         private GameObject survivorGameObject;
    10.         private Transform survivorTransform;
    11.         private int health;
    12.         private float survivorVelocity;
    13.         private float survivorDrag;
    14.         private float survivorAngularDrag;
    15.  
    16.  
    17.         public SurvivorClass (GameObject survivorGameObject, WeaponClass weapon, int health, float survivorVelocity)
    18.         {
    19.             this.weapon = weapon; //Default constructor. Pistol.
    20.             this.survivorGameObject = survivorGameObject;
    21.             this.health = health;
    22.             this.survivorVelocity = survivorVelocity;
    23.             this.survivorTransform = this.survivorGameObject.transform;
    24.             this.survivorDrag = this.survivorVelocity / 5;
    25.             this.survivorAngularDrag = this.survivorDrag * 5;
    26.  
    27.             survivorTransform.rigidbody2D.drag = survivorDrag;
    28.             survivorTransform.rigidbody2D.angularDrag = survivorDrag;
    29.         }
    30.  
    31.         public float   getSurvivorVelocity() {return this.survivorVelocity;}
    32.         public Vector3 getSurvivorPos() {return this.survivorTransform.position;}
    33.         public Vector3 getSurvivorAngle() {return this.survivorTransform.eulerAngles;}
    34.         public WeaponClass getWeapon() {return this.weapon;}
    35.  
    36.         public void setSurvivorVelocity(float survivorVelocity) {this.survivorVelocity = survivorVelocity;}
    37.         public void setSurvivorAngle(Vector3 v3TouchedPos) {
    38.             Vector2 v2TouchedPos = new Vector2 (v3TouchedPos.x, v3TouchedPos.y);
    39.             Vector3 v3CurrentPos = Camera.main.WorldToScreenPoint (survivorTransform.position);
    40.             Vector2 v2CurrentPos = new Vector2 (v3CurrentPos.x, v3CurrentPos.y);
    41.             Vector2 v2DisplacDir = v2TouchedPos - v2CurrentPos;
    42.             Vector2 v2DisplacDir_Norm = v2DisplacDir.normalized;
    43.  
    44.             survivorTransform.right = v2DisplacDir_Norm;
    45.         }
    46.  
    47.         public void moveSurvivor(Vector2 v2TouchedPos) {
    48.             Vector3 v3CurrentPos = Camera.main.WorldToScreenPoint (survivorTransform.position);
    49.             Vector2 v2CurrentPos = new Vector2 (v3CurrentPos.x, v3CurrentPos.y);
    50.             Vector2 v2DisplacDir = v2TouchedPos - v2CurrentPos;v2DisplacDir.Normalize ();
    51.             survivorTransform.rigidbody2D.velocity = v2DisplacDir * this.survivorVelocity;
    52.  
    53.         }
    54.  
    55.         public void moveSurvivorAndLookAtPos(Vector3 v3TouchedPos) {
    56.             Vector2 v2TouchedPos = new Vector2 (v3TouchedPos.x, v3TouchedPos.y);
    57.             setSurvivorAngle (v3TouchedPos);
    58.             moveSurvivor(v2TouchedPos);
    59.         }
    60.     }
    61. }
    Now, I create another script attached to my main camera so that, when the game opens, it creates a reference to SurvivorClass and initializes it, like so:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using AssemblyCSharp;
    4.  
    5. public class StartGame : MonoBehaviour {
    6.  
    7.     public GameObject survivorGameObject;
    8.     private WeaponClass weapon;
    9.     private SurvivorClass survivor;
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.         weapon = new WeaponClass ();
    14.         survivor = new SurvivorClass (survivorGameObject, weapon, 10, 6.0f);
    15.  
    16.     }
    17. }

    And now my question. When I move my character (survivor) by using other script (Move.cs), I need to know what her/his velocity is by retrieving this data from the instance created at the start of the game (by using: survivor.getSurvivorVelocity()).

    Another scenario in which I would need to access this instance would be in the case the player takes a "power-up" drink: in this case I would need to modify its speed, health, ... and so on.

    So, in a nutshell: I create an instance of SurvivorClass at the beginning of the game, and I need to access this instance from all other scripts of my game, modifying/reading it.

    How can I achieve this?

    Thank you in advance!
     
    Last edited: Aug 6, 2014
  2. Fluzing

    Fluzing

    Joined:
    Apr 5, 2013
    Posts:
    815
  3. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Oh, I didn't know about the static modifier. Now everything is a lot more clear,

    Thanks for your help!
     
  4. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    I forgot to ask if there is any way to avoid multiple intializations of a class. Is there? (Just to avoid mistakes at coding)
     
  5. Fluzing

    Fluzing

    Joined:
    Apr 5, 2013
    Posts:
    815
    What do you mean exactly? How are you initializing classes?
     
  6. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Ok, I asked nothing, that didn't make sense. Thanks for your help again
     
  7. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    I came up with another trouble regarding my first question. If I put a script (named StartGame.cs) in my Main camera creating an instance of SurvivorClass, I need to call the constructor I defined, like so:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using AssemblyCSharp;
    4. public class StartGame : MonoBehaviour {
    5.     public GameObject survivorGameObject;
    6.     private static WeaponClass weapon;
    7.     private static SurvivorClass survivor;
    8.     // Use this for initialization
    9.     void Start () {
    10.         weapon = new WeaponClass ();
    11.         survivor = new SurvivorClass (survivorGameObject, weapon, 10, 6.0f);
    12.     }
    13. }
    But the problem arises whenever I try to access my "survivor" instance from any other script. Imagine a case where I needed to know the survivor's health, just to check if she/he is dead or not. If I create another instance of my SurvivorClass, I must call its constructor, and this will definitely overwrite the original configuration (i.e. the health and speed properties initially set up when the game first ran up).

    This suggests me that, although part of the solution is using statics, it is not the entire solution: I need to initialize my "SurvivorClass" once and just once, and be able to access it from any other script.

    Any ideas? Thanks!
     
  8. Sven-Frankson

    Sven-Frankson

    Joined:
    May 29, 2014
    Posts:
    27
    Hi,

    Code (CSharp):
    1.  
    2. private static MyClass myStaticObject = null;
    3. public static MyClass MyStaticObject {
    4.     get {
    5.         if (myStaticObject == null) {
    6.             myStaticObject = new MyClass ();
    7.         }
    8.         return myStaticObject;
    9.     }
    10. }
    11.  
    This should do the job.

    Have a nice day !
     
  9. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Hello Sven. How is that code going to help me in case I need to access an instance declared in a script attached to my main camera? Say:

    1.) I create an instance of "SurvivorClass" in StartGame.cs (attached to Camera.main)
    2.) I need to access that instance from within other script, for example GiveHealth.cs. This is because if I try to create another instance, I will need to go through the constructor, and I don't want this. I need to Give Health to my already-created instance, not to a new instance.

    Could you help me? Thanks!
     
  10. Sven-Frankson

    Sven-Frankson

    Joined:
    May 29, 2014
    Posts:
    27
    More specifically, it should be something like this then :)

    Code (CSharp):
    1.  
    2. private static SurvivorClass survivorInstance = null;
    3.         public static SurvivorClass SurvivorInstance {
    4.             get {
    5.                 if (survivorInstance == null) {
    6.                     survivorInstance = FindObjectOfType<SurvivorClass> ();
    7.                     if (survivorInstance == null) {
    8.                         survivorInstance = Camera.main.gameObject.AddComponent<SurvivorClass> ();
    9.                     }
    10.                 }
    11.  
    12.                 return survivorInstance;
    13.             }
    14.         }
    15.  
     
  11. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Hello again Sven. May you teach me what does the " get { ... } " do? Why are you using the keyword "get" and what it is used for?

    EDIT: I don't know where to use the code you gave me above, and what it is intended to do. Maybe you could explain me what it does and where to use it? Thanks :)
     
  12. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    No one? I thought this would be easier! Any help is appreciated
     
  13. Sven-Frankson

    Sven-Frankson

    Joined:
    May 29, 2014
    Posts:
    27
  14. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Hello again Sven. I must be dense today, but I don't know where to put that code. I created a figure and attached it to this message. Where in that picture do I have to use that code? Is it necessary? duda.png
     
  15. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Already came up with the solution:

    From Script nº1) I define:

    Code (CSharp):
    1. public static SurvivorClass survivor = new SurvivorClass(...)
    And from Script nº215) I write:

    Code (CSharp):
    1. Script1.survivor.<method/variable>
    So now I consider my answer as solved. Thanks guys.