How to make one script instance reference another.

Hello!

I’ve been pondering a bit and I can’t quite get this to work using unity components.
I apologize for the long text, but I hope some of you gurus still can read through and suggest something to help me :slight_smile:

My problem is:

I have a list of player characters. This list contains a number of class instances, which (simplified) look something like this:

public class Character 
{

	public GameStatics.CharacterClass characterClass;
	public string name;	
	public int health;
        public int strength;
}

I add the class to a static list which I keep into a static class like so:

GS.characterList.Add(new Character());

So, I have a list of the characters easily available, and when I start the game, I can select character by setting the index into the list, and I can use this inside the level like this:

GS.characterList[GS.playerIndex].health = 20;

And here’s another practical thing:

I can create a new class instance at the start, like so:

Character player = new Character();
player = GS.characterList[GS.playerIndex];

So, I can then write:

player.health = 20

and the other class instance will also get the change.

So, you can see this is all good, except one problem:
However, since I don’t inherit from monobehaviour, I don’t see the values in the inspector. I would really like to inspect, and adjust the Character fields easily.

So I wonder, what’s the best way of doing what I described above using a monobehaviour?

I tried to setup the character class to inherit from monobehaviour, but those can’t be instanciated using new keyword.

They must be instanciated using AddComponent(). So I need to create a gameobject, add the component, and add the gameobject to my static list.

I thought I could get to the content of the static list like so:

Character player = GS.characterList[GS.playerIndex].GetComponent<Character>();

and I can then reference it’s fields like I did before:

player.health = 20;

But “player” ends up as a null, so it looks like the objects inside my static list are destroyed as I load the level.
I thought a static list should keep it’s contents also after level load?

So, what to do?

Kjetil

You can inherit ScriptableObject if you wish not to make a MonoBehaviour but still have it be editable in inspector. Though you’ll need to program a way to make a .asset of it. and i don’t think this is the best way to go about what your trying to do knowing what little i do about the project.

use this:
Character player = ( new GameObject(“scriptCharacter”, typeof(Character)) ).GetComponent();

if your Character script needs other components you just use the RequireComponent attribute and that constructor call to GameObject will automatically put the other types in.

So with those changes you should be set.

The one thing you may want to do, if you do not what the Character to be destroyed when the level is changed, use

GameObject.DontDestroyOnLoad( player.gameObject );

also this code here:

Character player = new Character();
player = GS.characterList[GS.playerIndex];

classes in C# are by reference. So your making a new instance and then immediately forgetting it by setting it to the reference of the element in the characterList array/container.

Hey! Thanks a bunch for the feedback! Appreciate it! It seems to me scriptableobject is maybe not most practical way of solving this, as you also mentioned.

Character player = ( new GameObject(“scriptCharacter”, typeof(Character)) ).GetComponent();

This thing is fine, I do get access to it. However, I would like it to “link” directly to the gameobject located in the static list, if you understand what I mean…? That’s why I did this:

Character player = new Character();
player = GS.characterList[GS.playerIndex];

I want player to be linked to the selected character in the list. That way I have an inspectable player, and the static list with that player is also updated, as it has a “link”.

This worked when I popuplated the “characterList” with Character instances that does not inherit from monobehaviour, and they are also not destroyed when loading a new level.

However, when I populate the “characterList” with gameobjects with a Character monobehaviour components, then these gameobjects are destroyed on level load.

I’m thinking I might use a singleton, instead of a static class. Then I should be able to inspect it directly.

I haven’t used that approach before, but always fun to learn something new :slight_smile:

Thanks again! :slight_smile:

Kjetil

Hey, So like i mentioned if you change what i put like this:

Character player = ( new GameObject(“scriptCharacter”, typeof(Character)) ).GetComponent();
GameObject.DontDestroyOnLoad( player.gameObject );

It wont destroy on a new level.