Persist GameObject information across all scripts

[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:

using System;
using UnityEngine;

namespace AssemblyCSharp
{
    public class SurvivorClass
    {
        private WeaponClass weapon;
        private GameObject survivorGameObject;
        private Transform survivorTransform;
        private int health;
        private float survivorVelocity;
        private float survivorDrag;
        private float survivorAngularDrag;


        public SurvivorClass (GameObject survivorGameObject, WeaponClass weapon, int health, float survivorVelocity)
        {
            this.weapon = weapon; //Default constructor. Pistol.
            this.survivorGameObject = survivorGameObject;
            this.health = health;
            this.survivorVelocity = survivorVelocity;
            this.survivorTransform = this.survivorGameObject.transform;
            this.survivorDrag = this.survivorVelocity / 5;
            this.survivorAngularDrag = this.survivorDrag * 5;

            survivorTransform.rigidbody2D.drag = survivorDrag;
            survivorTransform.rigidbody2D.angularDrag = survivorDrag;
        }

        public float   getSurvivorVelocity() {return this.survivorVelocity;}
        public Vector3 getSurvivorPos() {return this.survivorTransform.position;}
        public Vector3 getSurvivorAngle() {return this.survivorTransform.eulerAngles;}
        public WeaponClass getWeapon() {return this.weapon;}

        public void setSurvivorVelocity(float survivorVelocity) {this.survivorVelocity = survivorVelocity;}
        public void setSurvivorAngle(Vector3 v3TouchedPos) {
            Vector2 v2TouchedPos = new Vector2 (v3TouchedPos.x, v3TouchedPos.y);
            Vector3 v3CurrentPos = Camera.main.WorldToScreenPoint (survivorTransform.position);
            Vector2 v2CurrentPos = new Vector2 (v3CurrentPos.x, v3CurrentPos.y);
            Vector2 v2DisplacDir = v2TouchedPos - v2CurrentPos;
            Vector2 v2DisplacDir_Norm = v2DisplacDir.normalized;

            survivorTransform.right = v2DisplacDir_Norm;
        }

        public void moveSurvivor(Vector2 v2TouchedPos) {
            Vector3 v3CurrentPos = Camera.main.WorldToScreenPoint (survivorTransform.position);
            Vector2 v2CurrentPos = new Vector2 (v3CurrentPos.x, v3CurrentPos.y);
            Vector2 v2DisplacDir = v2TouchedPos - v2CurrentPos;v2DisplacDir.Normalize ();
            survivorTransform.rigidbody2D.velocity = v2DisplacDir * this.survivorVelocity;

        }

        public void moveSurvivorAndLookAtPos(Vector3 v3TouchedPos) {
            Vector2 v2TouchedPos = new Vector2 (v3TouchedPos.x, v3TouchedPos.y);
            setSurvivorAngle (v3TouchedPos);
            moveSurvivor(v2TouchedPos);
        }
    }
}

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:

using UnityEngine;
using System.Collections;
using AssemblyCSharp;

public class StartGame : MonoBehaviour {
  
    public GameObject survivorGameObject;
    private WeaponClass weapon;
    private SurvivorClass survivor;

    // Use this for initialization
    void Start () {
        weapon = new WeaponClass ();
        survivor = new SurvivorClass (survivorGameObject, weapon, 10, 6.0f);

    }
}

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!

I think you need this:

https://unity3d.com/learn/tutorials/modules/intermediate/scripting/statics

Oh, I didn’t know about the static modifier. Now everything is a lot more clear,

Thanks for your help!

I forgot to ask if there is any way to avoid multiple intializations of a class. Is there? (Just to avoid mistakes at coding)

What do you mean exactly? How are you initializing classes?

Ok, I asked nothing, that didn’t make sense. Thanks for your help again

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:

using UnityEngine;
using System.Collections;
using AssemblyCSharp;
public class StartGame : MonoBehaviour {
    public GameObject survivorGameObject;
    private static WeaponClass weapon;
    private static SurvivorClass survivor;
    // Use this for initialization
    void Start () {
        weapon = new WeaponClass ();
        survivor = new SurvivorClass (survivorGameObject, weapon, 10, 6.0f);
    }
}

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!

Hi,

private static MyClass myStaticObject = null;
public static MyClass MyStaticObject {
    get {
        if (myStaticObject == null) {
            myStaticObject = new MyClass ();
        }
        return myStaticObject;
    }
}

This should do the job.

Have a nice day !

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!

More specifically, it should be something like this then :slight_smile:

private static SurvivorClass survivorInstance = null;
        public static SurvivorClass SurvivorInstance {
            get {
                if (survivorInstance == null) {
                    survivorInstance = FindObjectOfType<SurvivorClass> ();
                    if (survivorInstance == null) {
                        survivorInstance = Camera.main.gameObject.AddComponent<SurvivorClass> ();
                    }
                }

                return survivorInstance;
            }
        }

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 :slight_smile:

No one? I thought this would be easier! Any help is appreciated

You access SurvivorInstance as you would access to any static variable. If you read it, it calls “get”, returning survivorInstance after some computations if necessary.

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?

Already came up with the solution:

From Script nº1) I define:

public static SurvivorClass survivor = new SurvivorClass(...)

And from Script nº215) I write:

Script1.survivor.<method/variable>

So now I consider my answer as solved. Thanks guys.