Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Creating a new Contains method to find objects of a specific type

A topic by ChronicReplay created Dec 20, 2020 Views: 368 Replies: 3
Viewing posts 1 to 4
(+1)

Hey everyone!

I found it super awesome that people here are really supportive to new game developers. I have a small question about creating new Contain methods for data structures other than primitive data types. I'll try my best to explain what I mean, I've created a Scriptable Object called Item that I want to add to my game. The new method I wanted to incorporate was ContainsItem to check if my inventory contains a specific Item. 


I was hoping to call ContainsItem to an array of Items, Item[], but it gives me this error.

How do I resolve an issue like this? Thanks in advanced!

Moderator moved this topic to General Development
(1 edit) (+1)

Hello! I fear this answer comes too late or that I'll be 'necroing' the post (I'm really sorry if that's the case) but I've just found it and I was a little bit surprised that this got no solution posted yet or maybe because this has passed unnoticed.

The solution is actually very simple. You placed the method in the 'Item' class instead of placing it in the 'Inventory' class. The inventory is the container, so the logical thing is to place the Contains check in it.

More little things. (A little off-topic but I consider good to point out) 

You can use Lists instead of Arrays, so you can use a good bunch of already implemented functions in C# as 'Contains':

public List<Item> Inventory;
...
if(Inventory.Contains(myItem)) { ... }

You can override the Equals in the Item class too, if you consider it necessary.

Another little thing: I've noticed that you're trying to simulate properties (in this case, with getter but not setter) in the Item class.

Just to follow a better convention here on how to do things, I'd recommend you use properties with backing fields. Something like this:

[SerializeField] private string testField;
public string TestField { get { return testField; } set { testField = value; } }

You can remove the setter part in your case, of course... and about naming conventions..., follow what you find more comfortable working with.

Now... beware of auto-properties, because Unity inspectors do not show those in the Editor with Monobehaviours and ScriptableObjects:

public string TestField { get; set; }

I know it's odd, but it's a Unity thing, I had a lot of frustration myself with this too.

And here some small reading on Lists and the Array vs Lists question

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?vi...

https://www.gamasutra.com/blogs/RobertZubek/20150504/242572/C_memory_and_perform...

And some about exposing properties in inspectors

https://forum.unity.com/threads/exposing-properties-in-the-inspector.471363/

https://answers.unity.com/questions/14985/how-do-i-expose-class-properties-not-f...

Again, sorry in case of necroposting. 

Anyway, hopefully this will help you a bit.

(3 edits)

Hey Cimeto, 

Thanks for the helpful tips so far, I'll look into using Lists instead of Arrays. After posting the question, I've worked on it a little bit and noticed that I should've declared a separate class for Inventory, and use a List<Item> to represent it as you pointed out. I looked up the Contains method for the List data structure and it seems like it has the Contains() method I needed the entire time.  Whoa, what's that set and get thing, I learned about that yet. Does that automatically act as my getter and setter methods in C#? So, the auto-properties you were talking about are essentially values that are automatically assigned to empty fields right?


Thanks for the help so far :)

(+1)

Hello! Glad that helped you a little!

I'm adding a few links with this post so you can learn properly, but yeah, you were trying to achieve with private fields and manually implemented functions what can be done with properties.

A field is a way to store a variable like so:

public float TestFloat;
private string testString;

Its values can be read or changed. Private fields can only be accessed in the same class, and public fields can be accessed outside the class. Something you already used in your code.

But properties are an interesting thing. You can control what's going out or in with them. You can even alter the result or play with it. 

Now an example:

public float MyValue;
public float HalfMyValue { get { return MyValue/2; } } 

In this example I have a public field and a public property. The property 'HalfMyValue' does not allow to change any value (no setter), but it will give you always half the value of the MyValue field.

Properties are actually a full structure of a backing field and get and set functions. So beware, they are not the same as a field. And in some way, they are considered syntactic sugar (not a bad thing, they make easier/faster to write code).

Auto-properties, or autoimplemented properties have this look:

public float MyValue { get; set; }

And they are a contracted way (write less) to make this:

private string myValue;
public string MyValue{ get { return myValue; } set { myValue = value; } }

These two offer the same functionality as a public field (public and no limitations or changes to the value).

The thing is, that Unity inspectors do not work with auto-properties. A lot of people already requested the feature... but... well... not there yet. 

I'm adding now proper reading about this, surely they can explain the subject a lot better than me:

https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-fiel...

https://www.jeremymorgan.com/blog/programming/properties-vs-fields/

https://forum.unity.com/threads/c-use-of-auto-properties-in-unity.200114/

https://stackoverflow.com/questions/1180860/public-fields-versus-automatic-prope...

https://softwareengineering.stackexchange.com/questions/161303/is-it-bad-practic...

The fight now is when is or what is correct to use, one or the other, because in the professional development world... public fields are a no-no, they are bad practice and you should stick with public properties instead, but yeah... then we have Unity Editor and its inspectors, where we need those public fields if we want to access them when designing a game.

I've a lot of frustration about this (and I still have) because of my experience on business software development, but hopefully, this video will ease your mind:

And yeah, I know it's a big post... but hopefully you've learned a few things on the way that could help you a lot.

Best of lucks!!