- Home /
If statements with Lists
Hey all, I have started to use Lists recently to save Quest variables, but I am having trouble finding out how to check if something exists (for an 'if' statement) currently my code looks like this:
if (questHandler.questHolder.Exists(x => x.questName == questName))
{
int num = this.convoLine;
switch (num)
{
// (I have also created a list class here)
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[Serializable]
public class QuestHandler : MonoBehaviour
{
public string[] onQuests = {};
public string[] completedQuests = {"Mushrooms 1", "Mushrooms 2"};
public int mushKilled = 0;
public string questName;
public bool onQuest;
public bool cpltReq;
public List<QuestHandler> questHolder = new List<QuestHandler>();
public QuestHandler(string newQuestName, bool newOnQuest, bool newCpltReq)
{
questName = newQuestName;
onQuest = newOnQuest;
cpltReq = newCpltReq;
}
void Start()
{
// Create a new member of List
questHolder.Add(new QuestHandler("Mushrooms 1", false, false));
}
}
Edit: Just remembered i should be more clear about what i want: How do I check if a certain part of a multi elemented (not sure what to call it) list exists? for example, for List["quest", true, true] how do i check if the first element is "quest"?
Not sure what you're asking for here, as you have the code that answers the question in the end of your post on the top of your post :/
If you do this, your start method will print "Contains the thing":
void Start() {
// Create a new member of List
questHolder.Add(new QuestHandler("$$anonymous$$ushrooms 1", false, false));
if(questHolder.Exists(x => x.questName == "$$anonymous$$ushrooms 1")) {
Debug.Log("Contains the thing!");
}
else {
Debug.Log("Does not contain the thing!");
}
}
Not an answer, but general coding tip:
There's an issue with your code - $$anonymous$$onoBehaviours shouldn't have constructors, as those won't be called by Unity on startup (Unity can't know what constructor arguments to use). If you run your code as is, Unity will give you a warning message. In addition, a Quest isn't conceptually a behavior - it's a container of information about a quest.
So, you should extract the questName, onQuest and cpltReq variables to an own (probably inner) Quest class. Your code would look something like:
public class QuestHandler : $$anonymous$$onoBehaviour {
public class Quest {
public int mush$$anonymous$$illed = 0;
public string questName;
public bool onQuest;
public bool cpltReq;
public Quest(string newQuestName, bool newOnQuest, bool newCpltReq) {
questName = newQuestName;
onQuest = newOnQuest;
cpltReq = newCpltReq;
}
}
public Quest[] onQuests = { };
public Quest[] completedQuests = {};
List<Quest> questHolder = new List<Quest>();
void Start() {
questHolder.Add(new Quest("$$anonymous$$ushrooms 1", false, false));
questHolder.Add(new Quest("$$anonymous$$ushrooms 2", false, false));
}
}
I'm not sure what you mean with the question. Do you want to have a list of QuestHandler, and check if there is a QuestHandler who's questName variable is "insertquestnamehere" in the list? In that case, the first part of your code is correct I believe.
However, your QuestHandler class has some problems a.t.m. Because $$anonymous$$onoBehaviours are by default serializable for Unity. Which means they don't need the Serializable attribute. Also, anything inheriting from UnityEngine.Object can't/shouldn't be instantiated through a constructor, (which you try to do at line 34)
What I think you want to do (but that is speculating really :p) is making 2 classes. 1 $$anonymous$$onoBehaviour, and 1 serializable class. Like so:
public class QuestHandler : $$anonymous$$onoBehaviour
{
public string[] onQuests = { };
public string[] completedQuests = { "$$anonymous$$ushrooms 1", "$$anonymous$$ushrooms 2" };
public int mush$$anonymous$$illed = 0;
public List<Quest> questHolder = new List<Quest>();
void Start()
{
// Create a new member of List
questHolder.Add(new Quest("$$anonymous$$ushrooms 1", false, false));
}
}
And:
[Serializable]
public class Quest
{
public string questName;
public bool onQuest;
public bool cpltReq;
public Quest(string newQuestName, bool newOnQuest, bool newCpltReq)
{
questName = newQuestName;
onQuest = newOnQuest;
cpltReq = newCpltReq;
}
}
Hey guys, thanks for the responses; sorry if i wasn't clear in my question (thanks Baste for fixing my code) What i am basically trying to achieve is
A quest holder (that i can save in the future)
But I'm not good with lists yet, and would preferably like to have pre-made lists that i can access and change for each quest (e.g. when i start the mushroom quest, the bool for onQuest is set to true in that list)
These lists would need to be accessible from another script (my quest giver script) to see if the conditions have been met (onQuest && cpltReq)
So right now I'm just really struggling to understand lists, and the documentation is even more confusing -.- Any more help would be greatly appreciated
Also, the code at the top didnt work, turned out that the variable is acting strange (i can figure that one out by myself)
@Baste, your code gives an inconsistent accessibility error (questHandler.Quest[] is less accessible than QuestHandler.onQuests
I noticed, and edited the Quest class to be public. Seems that it didn't stick the first time around, fixed it now.
yep i figured that out, thanks
Still would like an answer to the original question: how would I check to see if the quest is active (in the list it is the second element Boolean)? I can't figure out the function to check if the array bool is true for the quest. In the wrong terms: how do I check what 'x' is in the following: myList["mushrooms 1", x, false]
Answer by Tommynator · Nov 28, 2014 at 05:59 PM
Basically you got the answer from Baste already. You have to use the list function "Exists" and create a lambda expression to check if the quest is active.
public bool IsQuestActive(string quest)
{
return questHolder.Exists(q => q.questName == quest && q.onQuest == true);
}
Alternatively you use the list function "Find" and evaluate the quest object afterwards.
public bool IsQuestActive(string name)
{
Quest quest = questHolder.Find(q => q.questName == name);
return quest != null && quest.onQuest == true;
}
In general I have the feeling that you have a wrong understanding of what a generic list is. A list of type T only contains items of type T, nothing else. In your case the list only contains Quest objects. The Quest happens to have members like bools and strings, but that has nothing to do with the list itself. Hope that helped a bit? :)
Thanks! I don't think it's possible to select two answers so I selected yours since it made more sense to me :) On a side note, does that mean a list is like an array but elements can be removed? What's really confusing me is selecting the index of the list value (is quest[0] the index for quest["mushrooms 1", false, false] or would it be quest[0,0,0])?
You can treat a list exactly like an one-dimensional array, as you can access the elements only by index. So questHolder[0] would refer to the first quest object, questHolder[1] to the second and so on. The key difference to an array is, that the size is not fix and you can dynamically add and remove elements. As for arrays you can also use a for-loop to iterate through the list: for(int i=0; i < questHolder.Count; i++) { Quest q = questHolder[i]; Debug.Log(q.questName + " " + q.onQuest); }
Oh cool thanks! So would that make questHolder[1] = false (that is if the quest holder is questHolder["$$anonymous$$ushrooms 1", false, false])?
Edit: got it! Thanks for your help everyone, I'm so grateful!
Your answer
![](https://koobas.hobune.stream/wayback/20220613172632im_/https://answers.unity.com/themes/thub/images/avi.jpg)