C#, Sprite loading problem,Generic List, Inheritance

 public class Archer : BaseCompanion {
     public static Archer archer;
     public Sprite face;
     int x = 32492348;
     public override Sprite faceSprite {
         get {
             return face;
         }
     }
     public override int testInt {
         get {
             return x;
         }
     }
     void Awake(){
         face = Resources.Load ("0115", typeof(Sprite)) as Sprite;
     }
}
 public class MyCompanionManager : MonoBehaviour {
     public List<BaseCompanion> myKnownComps = new List<BaseCompanion>();
     Archer archer = new Archer ();
     public Sprite sprity;
     void Awake()
     {
     //    myCompanionManager = this;
     }
     // Use this for initialization
     void Start () {
         SpriteRenderer sr = gameObject.AddComponent<SpriteRenderer> () as SpriteRenderer;
         myKnownComps.Add(archer);
         Debug.Log (myKnownComps[0].testInt);
         sprity= myKnownComps[0].faceSprite;
         sr.sprite = sprity;
         AddCompanion ();
     }

Line 14 isnt working and I dont understand why. The int testInt can be accessed but for the Sprite I get null.

Most likely this line isn’t loading anything:

face =Resources.Load(“0115”, typeof(Sprite))as Sprite;

I does load the image, I debugged inside archer and made a renderer for testing and it displayed the sprite. Thats why im so puzzled. If I debug faceSprite inside Archer its != null, if I access via index from outside its null.

You have instantiated Archer by using the new command. new should not be used for UnityEngine.Components, so I assume it is not one. Since it is not a Component, it is also not a MonoBhevaiour, which means its Awake function will not be called automatically. I do not see that you are calling it anywhere manually, so I assume the sprite is never loaded.

2 Likes
public abstract class BaseCompanion : MonoBehaviour {

    public abstract Sprite StandingSprite{ get; }
    public abstract Sprite faceSprite{ get; }
    public abstract Sprite attackSprite{ get; }

    public abstract int testInt { get;}

    public virtual void CompanionSkill(){
    }

    public virtual void passiveSkill(){
    }

}

This my parent class, and no I have not called manually anything. If its not too much of a bother can you tell where and what I have to modify to make it work?

My guess is that your line 3 in MyCompanionManager is wrong. You shouldn’t “new up” a UnityEngine.Component. Instead, add the script to your prefab or use GameObject.AddComponent() to add one programmatically.

Hmmm, this is soo confusing. You see i setup

 public override Sprite faceSprite {
         get {
             return face;
         }
     }

and dragging a sprite into its Inspector Face slot. If I do a new Archer(), shouldnt that work ?? Because it doesnt and I dont use awake or start for assigning the sprite.

The thing is I dont want it to be active yet, only know all its data.

No. you dragged a sprite into the Inspector in the Unity Editor. The Editor serializes this prefab with a reference to the correct sprite. If you use the new command, then an object is instantiated but it does not get its properties assigned through deserialization. Thus, the face parameter is initialize according to the class rules. Since Sprite is a reference type, it is initialized with a null value.

This is why Components are not supposed to be created using the new operator. You should use AddComponent so that the object can be setup with the values you assigned in the editor.

If you dragged a sprite into the inspector, then you must have already added the Archer script to a GameObject. In that case, you can just use GetComponent() on this GameObject.

In the code you provided you assign the face property during Awake().

I don’t really understand what you mean

1 Like

Well if i Add them to as Component I have them all active on my GameObject which is not what I wanted, but maybe not even that much of a problem since i can just disable them. I guess I will need to make them all prefab and make a List of type GameObject? or could i still just add them into my List? Because as mentioned I need to sort them and have the first 3 ones active. But thx so far!!!

I’m curious. Does your Archer class represent a real actor in your game?

No, my Companions will be like items. They have a image, stats, and a unique behaviour when euqipped.

An alternative, since you don’t necessarily want your companions attached to a GameObject, is to make them inherit from ScriptableObject instead of MonoBehaviour. These things are not components, so they can’t be added to the player using AddComponent<>. They also won’t have Awake, Start, Update, etc… called on them automatically. However, they can still be referenced and stored in a list. Another MonoBehaviour script, such as your manager could be responsible for making calls to the correct companions.

1 Like

ok, I will look into ScriptableObject tomorrow. Going to bed for now. Thx alot for your help

Just wanna let you know. I made my companions now ScriptableObjects and it works exactly how i wanted it.
Thx!!