0

This is a common question and I assure you I have done my research first. I simply cannot get a list of all of the instances of a script type on the game object.

I have tried making an array of the types and looping the contents into a list. This gives me conversion errors.

I have tried directly adding the array to the list with .AddRange. Conversion errors.

I have tried the different formats of GetComponents, and casting the output of the array into every applicable type I can think of, with no success.

I have also tried initising the list first and then running GetComponent in start.

I have tried using CharEquipGenre as both monobehaviour and non-monobehaviour.

What am I doing wrong?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class CharEquipment : MonoBehaviour
{   
public List<CharEquipGenre> equipment_genres = GetComponents <CharEquipGenre>(); // I am trying to do something like this
public CharEquipGenre attack;
public CharEquipGenre defend;
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharEquipGenre
{
public List<BlockScriptableObject> equipped = new List<BlockScriptableObject>();
}

// Additional code via request:

public class CharEquipment : MonoBehaviour
{

void Start()
{
    equipment_genres = GetComponents<CharEquipGenre>();
}

public List<CharEquipGenre> equipment_genres = new System.Collections.Generic.List<CharEquipGenre>();

public CharEquipGenre attack;
public CharEquipGenre defend;
James
  • 81
  • 7
  • 2
    What error you get? – SᴇM Jul 11 '19 at 12:09
  • 2
    could you provide the data you are giving as input as this is not really clear what is not being converted correctly – Bruno Belmondo Jul 11 '19 at 12:09
  • This currently gives the error "A field initializer cannot reference the non-static field.... 'component.GetComponents()' – James Jul 11 '19 at 12:10
  • @James Try initializing equipment_genres in the constructor – 0x492559F64E Jul 11 '19 at 12:11
  • 1
    Sorry, maybe I am misunderstanding something: I am trying to get the "CharEquipGenre" attack and "CharEquipGenre" attack with GetComponents and have them placed in the list equipemtn_genres. – James Jul 11 '19 at 12:12
  • Possible duplicate of [A field initializer cannot reference the nonstatic field, method, or property](https://stackoverflow.com/questions/14439231/a-field-initializer-cannot-reference-the-nonstatic-field-method-or-property) – SᴇM Jul 11 '19 at 12:14
  • @James Then I guess what you want is reflection on your type. Something along the lines of CharEquipment.GetType().GetProperties() – 0x492559F64E Jul 11 '19 at 12:14
  • 2
    GetComponents works on Monobehaviour class, but your CharEquipGenre doesn't inherit from it. – Eyap Jul 11 '19 at 12:15
  • I added the initised code above, that gives me "Cannot implicitly convert type "CharEquipGenre[]" to Systems.Generic.List" – James Jul 11 '19 at 12:16
  • @Eyap I have tested the above with monobehaviour in and out of the CharEquipGenre class. – James Jul 11 '19 at 12:17
  • @James Try variations of: List mylist = typeof(CharEquipment).GetProperties().Where(t => t is CharEquipGenre).ToList(); – 0x492559F64E Jul 11 '19 at 12:22
  • I get Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List' when using this method, but I think you revealed some avenues for me to pursue so I'm doing that now. – James Jul 11 '19 at 12:44
  • Possible duplicate of [a field initializer cannot reference the nonstatic field method or property 'Component.GetComponent()'](https://stackoverflow.com/questions/39241408/a-field-initializer-cannot-reference-the-nonstatic-field-method-or-property-com) – Ruzihm Jul 11 '19 at 19:18

3 Answers3

3

Well, CharEquipGenre is not a MonoBehaviour, so there are no "components" of this class.

You can find all components of a specific type with GetComponents (read more here) but it needs to be a MonoBehaviour that's attached to the GameObject

asaf92
  • 1,557
  • 1
  • 19
  • 30
  • I have tested the above with monobehaviour in and out of the CharEquipGenre class. Your answer is interesting though, thanks. – James Jul 11 '19 at 12:19
  • 2
    If by "in and out" you mean "when CharEquipGenre inherits from MonoBehaviour and when it doesn't" than you probably did something wrong. Provide a code example where you're trying to find all components of a certain MonoBehaviour class on a GameObject where there are components of said type and show us that it still doesn't work – asaf92 Jul 11 '19 at 12:21
1

I don't know unity3d but it seems as though you are trying to initialize equipment_genres when defining it and for that the compiler would need access to something that is available at compile time.

If GetComponents is a method on the class then this will not work as the method is not static. You could use the instance by perhaps going with a method or expression body:

    public List<CharEquipGenre> equipment_genres => new List<CharEquipGenre>(GetComponents<CharEquipGenre>());

Although a slightly "better" design would be exposing IEnumerable:

    public IEnumerable<CharEquipGenre> EquipmentGenres => ...
    // or
    public IEnumerable<CharEquipGenre> GetEquipmentGenres() => ...
Eben Roux
  • 12,983
  • 2
  • 27
  • 48
0

First of all make your class [Serializable] so you can see it in the inspector and save it.

[Serializable]
public class CharEquipGenre
{
    public List<BlockScriptableObject> equipped = new List<BlockScriptableObject>();
}

And then simply instantiate a new list like

public List<CharEquipGenre> equipment_genres = new List<CharEquipGenre>();

Note that both of those will be overruled by whatever you do to them in the Inspector later. Once you added elements any change to the initialization lines is useless (unless you hit Reset in the MonoBehaviour's context menu)

derHugo
  • 83,094
  • 9
  • 75
  • 115