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

C#, Sprite loading problem,Generic List, Inheritance

Discussion in 'Scripting' started by Snicky, Jul 24, 2015.

  1. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    Code (CSharp):
    1.  public class Archer : BaseCompanion {
    2.      public static Archer archer;
    3.      public Sprite face;
    4.      int x = 32492348;
    5.      public override Sprite faceSprite {
    6.          get {
    7.              return face;
    8.          }
    9.      }
    10.      public override int testInt {
    11.          get {
    12.              return x;
    13.          }
    14.      }
    15.      void Awake(){
    16.          face = Resources.Load ("0115", typeof(Sprite)) as Sprite;
    17.      }
    18. }
    Code (CSharp):
    1.  public class MyCompanionManager : MonoBehaviour {
    2.      public List<BaseCompanion> myKnownComps = new List<BaseCompanion>();
    3.      Archer archer = new Archer ();
    4.      public Sprite sprity;
    5.      void Awake()
    6.      {
    7.      //    myCompanionManager = this;
    8.      }
    9.      // Use this for initialization
    10.      void Start () {
    11.          SpriteRenderer sr = gameObject.AddComponent<SpriteRenderer> () as SpriteRenderer;
    12.          myKnownComps.Add(archer);
    13.          Debug.Log (myKnownComps[0].testInt);
    14.          sprity= myKnownComps[0].faceSprite;
    15.          sr.sprite = sprity;
    16.          AddCompanion ();
    17.      }
    Line 14 isnt working and I dont understand why. The int testInt can be accessed but for the Sprite I get null.
     
  2. Deleted User

    Deleted User

    Guest

    Most likely this line isn't loading anything:

    face =Resources.Load("0115", typeof(Sprite))as Sprite;
     
  3. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    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.
     
  4. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    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.
     
    Mycroft and Deleted User like this.
  5. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    Code (CSharp):
    1. public abstract class BaseCompanion : MonoBehaviour {
    2.  
    3.     public abstract Sprite StandingSprite{ get; }
    4.     public abstract Sprite faceSprite{ get; }
    5.     public abstract Sprite attackSprite{ get; }
    6.  
    7.     public abstract int testInt { get;}
    8.  
    9.     public virtual void CompanionSkill(){
    10.     }
    11.  
    12.     public virtual void passiveSkill(){
    13.     }
    14.  
    15. }
    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?
     
  6. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    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<Archer>() to add one programmatically.
     
  7. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    Hmmm, this is soo confusing. You see i setup
    Code (CSharp):
    1.  public override Sprite faceSprite {
    2.          get {
    3.              return face;
    4.          }
    5.      }
    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.
     
  8. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    The thing is I dont want it to be active yet, only know all its data.
     
  9. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    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<Archer>() on this GameObject.

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

    I don't really understand what you mean
     
    Snicky likes this.
  10. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    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<BaseCampanion>? Because as mentioned I need to sort them and have the first 3 ones active. But thx so far!!!
     
  11. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    I'm curious. Does your Archer class represent a real actor in your game?
     
  12. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    No, my Companions will be like items. They have a image, stats, and a unique behaviour when euqipped.
     
  13. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    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.
     
    Snicky likes this.
  14. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    ok, I will look into ScriptableObject tomorrow. Going to bed for now. Thx alot for your help
     
  15. Snicky

    Snicky

    Joined:
    Mar 5, 2015
    Posts:
    36
    Just wanna let you know. I made my companions now ScriptableObjects and it works exactly how i wanted it.
    Thx!!