#how would you suggest I do that
1 messages · Page 1 of 1 (latest)
lemme write a little something up
what defines a quest right now?
the kind of fish, the number of fish, the XP reward...
so theres a random amount which is set
between 2 values
per fish
then a random amount of quests, maxinum of 3
and then the XP reward
does each kind of fish have its own range of minimum and maximum # of fish to catch?
or is it the same range for everyone
currently its the same
so you really just need to know a list of all the kinds of fish that exist
and then make quests by picking a fish + count + xp reward
currently only 3 fish, but over the next week ill be adding a tonne more
I would like the script to be alot simpler to setup...
do you have a Fish class or something?
In my fish script, I have a enum list with the different fish
and prefabs of the different kinds of fish
^
Currently yes
1 script, with multiple pre-fabs with different models really
then I select the fish type on the editor
okay, so there are multiple prefabs
and it changes all their stats
you've said that there's only one prefab and that there are multiple prefabs :p
lol, Currently I only have 1 fish ahaha
is the plan, eventually, to have many prefabs, each of which is configured to be a certain kind of fish?
Yep
okay, so we'll roll with that
so, here's my suggestion
give the quest controller a List<Fish>
this will let you make a list of prefabs with a Fish component
maybe public List<Fish> fishChoices;
now, we need to store our quest data
you could create a struct to hold the data
[System.Serializable]
public struct Quest {
public Fish fish;
public int count;
public int xp;
}
So what does a struct do?
a struct is similar to a class
it can hold many fields, and can have methods
the big distinction is that it's a value -- so if you do this...
public List<Quest> quests = new();
quests[0] = new Quest();
Quest myQuest = quests[0];
myQuest.fish = someFish;
...quests[0] will still have no fish
you made a copy when you got the quest out
It might be a little more convenient to just make a it a class, really
it's not like you're processing thousands of quests per frame and need the better performance a struct can give you :p
this seems very complicated ahaha
so, let's go with a class
[System.Serializable]
public class Quest {
public Fish fish;
public int count;
public int xp;
}
so, we have this bag of data
fish + count + xp
yep
can you have two quests for the same fish?
Nope
okay, so we can make things easier to work with
Dictionary<Fish, Quest>
this is a dictionary that lets you store a quest, identified by a fish prefab
or, maybe
Dictionary<FishKind, Quest>
where FishKind is whatever that enum is
what did you call the enum?
Lemme check
this would be better to use
otherwise you'd be associating a quest with a specific fish
like, literally one specific fish in the lake
which is less convenient :p
bingo
so
public class Quest {
public int count;
public int xp;
}
Dictionary<FishType, Quest> quests = new();
quests[FishType.GoldFish] = new Quest() {
count = 10,
xp = 30
};
we now have one quest
it wants us to catch 10 fish and will give 30 xp
that looks good
so here's the neat part
let's say you have a function that you run when you catch a fish
public void CatchFish(Fish fish) {
if(quests.ContainsKey(fish.fishtype)) {
quests[fish.fishtype].count -= 1;
if (quests[fish.fishtype].count == 0) {
Debug.Log("Quest done!");
quests.Remove(fish.fishtype);
}
}
}
when you catch a fish, you check if there is a quest for it
if there is, you reduce the count by 1
then, if the count is 0, you remove the quest
you'd give the player XP there
this way, no matter how many kinds of fish you have, that's all you have to write
So what does a dictionary actually do and hold?
you do the same thing for every kind of fish
a dictionary stores a value that you look up with a key
Dictionary<string, int> would let you do something like dict["hello"] = 123;
It's a good replacement for code that looks like this:
int goldfishCount = 3;
int tunaCount = 5;
int lobsterCount = 7;
instead
yeah, makes sense
counts[FishType.GoldFish] = 3;
etc.
now you don't need to add a whole new variable to add a new kind of fish
My fish script is a mess ahaha, its handling pretty much everything as I couldnt target 1 particular pre-fab from the other scripts
so that's the quest-completion side
quest-generation is also pretty simple
pick a fish type
then, store a new quest in the dictionary
hm
here's how I'd pick a random fish kind (it's mildly scary)
List<FishType> fishTypes = new();
foreach (FishType fishType in System.Enum.GetValues(typeof(FishType)))
fishTypes.Add(fishType);
int index = Random.Range(0, fishTypes.Count);
FishType chosen = fishTypes[index];
don't worry if that foreach line looks really weird (it is)
enums are a little funky
How long have you been coding for?
a decade-ish :p
damn, I can tell ahaha
a few years in C#
Ive been coding for around 6 months
System.Enum.GetValues takes an enum type and tells you all of the valid values
after that foreach loop runs, fishTypes will have every single FishType value in it
so, you can then pick a random item from the list
alright, so I know that my script is probably a mess, but it works so imma stick with it...
But
and, to expand on that a bit
How would I check whether all the tasks have been completed, then refresh them
I need to check whether they are active too
List<FishType> fishTypes = new();
foreach (FishType fishType in System.Enum.GetValues(typeof(FishType)))
fishTypes.Add(fishType);
while(fishTypes.Count > 0) {
int index = Random.Range(0, fishTypes.Count);
FishType chosen = fishTypes[index];
quests[chosen] = new Quest() {
count = 5,
xp = 5
};
fishTypes.Remove(chosen);
}
this would create a quest for every single kind of fish
what makes a quest active?
if the boolean goldfishQuest is true
so the first if statement is telling me the quest has been completed and its a active quest
are you asking how you'd do this when you store quests in a dictionary?
nah if I were to do it my way
it seems like you already check if the quest is active, then
Not sure if I wanna jump into doing dictionarys ahaha
but how would I merge all 3 statements together
As I need to check whether all the active tasks have been compoleted
in each if block, increment the counter
ah makes sense
yep ok
ill try that
I crashed my unity, Think I added a loop somewhere lol
if you do want to try switching to a dictionary, every place where you repeat yourself 3 times will be replaced with a single block of code
(or 4 times, or 5 times, or ...)
wrong order
wait no, cause its in update
you increment completed after checking it
and its in update currently, so will continue updating and adding 1
well, you should reset completed to 0 at the start
otherwise completing 1 quest would get the counter to 3 after 3 frames
so where should I put this, cause it cant go in update right?
yep
then it gets set to 0 straight away
In each of the loop of the update method, it should set the value completed to 0. It will then add 1 depending whether a quest is completed if its a active quest. It will then check if the number of quests complete is equal to the number of active quests, if it is, it will refresh the quests.
yep, that sounds reasonable to me
So weird my unity freezes if i tick all of them
it should just call the same thing as whats in start method..
any ideas
I think I know why
nope.. crashed again
📃 Large Code Blocks
Large code blocks should be posted as links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/
https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.
Did that link work?
hm, there's nothing obvious that would go into an infinite loop
which is what will freeze the editor
thats weird, I just refreshed the tasks fine, then when there was a full set of tasks, I did it again, and it froze
oh
you don't set goldfishQuest back to false
so it will be trying to add quests forever
it will think it has already made a quest for all three kinds of fish
so it'll never succeed at creating a quest
ah
Well spotted
thanks!
Also 1 last quick questiomn
I added a toon shader to my project a while back
Ive had to warnings in my console and im not sure how to fix them
any ideas?
Ahh and how would I update this? As its not in update.
should I set progress1.text to a value then update that value
Ill try taht
that
hm
I dunno about that.
int x = 1;
Progress1.text = x + "/" + 3;
x = 2;
this will not change the text
this is where it starts to get really annoying to have all this hard-coded stuff, you see :p
you're gonna have tons of duplicate code