Custom Condition Control and Timeline
Custom Condition Control and Timeline
Dear Pixel Crushers Team,
I hope you can help me with an issue I faced using the StartConversationClip in Unity's Timeline in combination with custom conditions that access C# scripts.
There are 2 Characters in my scene: Harald and Silvia.
You (the player) can talk to Harald, and Harald uses the Timeline Trigger Component to trigger a cutscene OnConversationEnd. The playableDirector sits on a different GameObject.
The cutscene is quite short:
Harald walks over to Silvia and Silvia says something to Harald.
In the timeline I use simple animation and a StartConversationClip for this that starts Silvia's conversation.
Sivlia has two different options of what to say to Harald. What Sivlia says during runtime is determined by a custom condition that depends on a boolean inside a C# script to which the dialogue database has access:
true-> Sivlia says Option 1 ;;; false -> Silvia says Option 2.
This works fine except that it calls the boolean from the wrong instance of the script - it should call it from Sivlia but it actually calls it from Harald who has the script attached, too.
I have no idea how to tell the dialogue manager to call the boolean function on Silvia.
Do you have any advice for me and/or a general explanation on how the dialogue database calls functions?
Also (out of curiosity) what does the Conversant mean/do that appears in the inspector when you select the StartConversationClip in the timeline? I assigned all kinds of stuff to it but I couldn't observe any effects...
Any help would be appreciated! Thank you in advance!
I hope you can help me with an issue I faced using the StartConversationClip in Unity's Timeline in combination with custom conditions that access C# scripts.
There are 2 Characters in my scene: Harald and Silvia.
You (the player) can talk to Harald, and Harald uses the Timeline Trigger Component to trigger a cutscene OnConversationEnd. The playableDirector sits on a different GameObject.
The cutscene is quite short:
Harald walks over to Silvia and Silvia says something to Harald.
In the timeline I use simple animation and a StartConversationClip for this that starts Silvia's conversation.
Sivlia has two different options of what to say to Harald. What Sivlia says during runtime is determined by a custom condition that depends on a boolean inside a C# script to which the dialogue database has access:
true-> Sivlia says Option 1 ;;; false -> Silvia says Option 2.
This works fine except that it calls the boolean from the wrong instance of the script - it should call it from Sivlia but it actually calls it from Harald who has the script attached, too.
I have no idea how to tell the dialogue manager to call the boolean function on Silvia.
Do you have any advice for me and/or a general explanation on how the dialogue database calls functions?
Also (out of curiosity) what does the Conversant mean/do that appears in the inspector when you select the StartConversationClip in the timeline? I assigned all kinds of stuff to it but I couldn't observe any effects...
Any help would be appreciated! Thank you in advance!
Re: Custom Condition Control and Timeline
Hi,
When you write a conversation, you can specify the conversation's primary Actor and Conversant. (In the Dialogue Editor, inspect a conversation and select Menu > Conversation Properties to see the primary Actor and Conversant dropdowns.)
When you set up a Dialogue System Trigger to start a conversation, you can specify the Conversation Actor and Conversation Conversant GameObjects. If these are assigned, then it will use these GameObjects for the active conversation's primary Actor and Conversant, even if those GameObject represent different actors than in the original conversation. More info: Character GameObject Assignments.
In Timeline, a Start Conversation clip will use the Start Conversation track's GameObject as the Conversation Actor. You can use the clip's Conversant field to specify the Conversation Conversant. If you leave it unassigned, the Start Conversation clip will look for the GameObject that represents the conversation's primary Conversant.
---
Are you registering your C# method with Lua so you can access it in dialogue entries' Conditions? If so, bear in mind that these Lua functions are global. If you register the C# method with Lua on Harald, then you can't also register the same method on Silvia. Since you can only register one instance of the C# method with Lua, you may need to pass the character name to the C# method. If your method is "IsBoolTrue()", then you may need to change it to "IsBoolTrue(string characterName)" so you can check IsBoolTrue("Harald") or IsBoolTrue("Silvia").
When you write a conversation, you can specify the conversation's primary Actor and Conversant. (In the Dialogue Editor, inspect a conversation and select Menu > Conversation Properties to see the primary Actor and Conversant dropdowns.)
When you set up a Dialogue System Trigger to start a conversation, you can specify the Conversation Actor and Conversation Conversant GameObjects. If these are assigned, then it will use these GameObjects for the active conversation's primary Actor and Conversant, even if those GameObject represent different actors than in the original conversation. More info: Character GameObject Assignments.
In Timeline, a Start Conversation clip will use the Start Conversation track's GameObject as the Conversation Actor. You can use the clip's Conversant field to specify the Conversation Conversant. If you leave it unassigned, the Start Conversation clip will look for the GameObject that represents the conversation's primary Conversant.
---
Are you registering your C# method with Lua so you can access it in dialogue entries' Conditions? If so, bear in mind that these Lua functions are global. If you register the C# method with Lua on Harald, then you can't also register the same method on Silvia. Since you can only register one instance of the C# method with Lua, you may need to pass the character name to the C# method. If your method is "IsBoolTrue()", then you may need to change it to "IsBoolTrue(string characterName)" so you can check IsBoolTrue("Harald") or IsBoolTrue("Silvia").
Re: Custom Condition Control and Timeline
Hi,
thanks for your help! A happy new year for you and your team!
Ah okay, I wasn't aware that if you register a function with Lua you could only have one instance of the respective C# script in the scene, so that's probably where the problem is.
My programming skills are somewhere between beginner and intermediate, so maybe you can give me some advice on how to handle this?
I have multiple characters in the scene. Depending on different variables they should say different things. At the moment there are only two variables: their energy level and their mood. There might be more variables in the future that affect conversation options. So far I have only hooked up the mood-variable with the dialogue system - this is the boolean I'm having trouble with.
I use the Lua functions to gain access to the character's variables and I originally planned to have the same C# script attached to every character in the scene (with different individual values). However, since you can only have one instance of the script in the scene, the only possibility I see is to somehow access all needed variables from a single script that either holds the variables of all characters or has access to all characters. Either way it would need to iterate through arrays or lists to find the right character. This shouldn't be an issue, since there are probably max 30 characters in the scene, however, this method seems quite clumsy to me.
I guess I'm not the first one to make characters say different things depending on their energy or health or whatsoever. Do you have a better idea how to do this or some "best practice" advice?
Thanks a lot!
thanks for your help! A happy new year for you and your team!
Ah okay, I wasn't aware that if you register a function with Lua you could only have one instance of the respective C# script in the scene, so that's probably where the problem is.
My programming skills are somewhere between beginner and intermediate, so maybe you can give me some advice on how to handle this?
I have multiple characters in the scene. Depending on different variables they should say different things. At the moment there are only two variables: their energy level and their mood. There might be more variables in the future that affect conversation options. So far I have only hooked up the mood-variable with the dialogue system - this is the boolean I'm having trouble with.
I use the Lua functions to gain access to the character's variables and I originally planned to have the same C# script attached to every character in the scene (with different individual values). However, since you can only have one instance of the script in the scene, the only possibility I see is to somehow access all needed variables from a single script that either holds the variables of all characters or has access to all characters. Either way it would need to iterate through arrays or lists to find the right character. This shouldn't be an issue, since there are probably max 30 characters in the scene, however, this method seems quite clumsy to me.
I guess I'm not the first one to make characters say different things depending on their energy or health or whatsoever. Do you have a better idea how to do this or some "best practice" advice?
Thanks a lot!
Re: Custom Condition Control and Timeline
Hi,
There are several ways you could approach this. Here's a suggestion that's fairly straightforward and flexible.
Let's assume each of your character GameObjects has a script like this:
Add a Dialogue Actor component to each character GameObject, and set the Actor field to the character's actor in your dialogue database. The Dialogue Actor component will register the character's GameObject with the Dialogue System, which makes it easy to access the GameObject at runtime without having to search the scene.
Add a script like the one below to the Dialogue Manager GameObject. This script will register Lua functions for each character attribute, where you can provide a character name and it will return that character's value.
For brevity, I omitted the 'using' statements at the top.
If you don't want to write a separate function for each attribute, you could write a single function that accepts two parameters: the character's name and the attribute to look up. It's up to whatever you prefer.
In your conversation nodes' Conditions fields, you can check attributes such as:
or
To avoid having to type "GetEnergyLevel(..." in your conversations' Conditions fields, you can create a Custom Lua Function Info asset as described in Registering Lua Functions. This way you can select your functions from the "..." dropdown menu.
There are several ways you could approach this. Here's a suggestion that's fairly straightforward and flexible.
Let's assume each of your character GameObjects has a script like this:
Code: Select all
public class CharacterAttributes : MonoBehaviour
{
public int energyLevel;
public int mood;
}
Add a script like the one below to the Dialogue Manager GameObject. This script will register Lua functions for each character attribute, where you can provide a character name and it will return that character's value.
Code: Select all
public class CharacterAttributesLua : MonoBehaviour
{
private void Awake()
{
Lua.RegisterFunction("GetEnergyLevel", this, SymbolExtensions.GetMethodInfo(() => GetEnergyLevel(string.Empty)));
Lua.RegisterFunction("GetMood", this, SymbolExtensions.GetMethodInfo(() => GetMood(string.Empty)));
}
private double GetEnergyLevel(string actorName)
{
CharacterAttributes characterAttributes = GetCharacterAttributes(actorName);
return (characterAttributes != null) ? characterAttributes.energyLevel : 0;
}
private double GetMood(string actorName)
{
CharacterAttributes characterAttributes = GetCharacterAttributes(actorName);
return (characterAttributes != null) ? characterAttributes.mood : 0;
}
private CharacterAttributes GetCharacterAttributes(string actorName)
{
Transform actor = GetRegisteredActorTransform(characterName);
if (actor == null)
{
Debug.LogWarning($"Can't find CharacterAttributes on {actorName}");
return null;
}
else
{
return actor.GetComponent<CharacterAttributes>();
}
}
}
If you don't want to write a separate function for each attribute, you could write a single function that accepts two parameters: the character's name and the attribute to look up. It's up to whatever you prefer.
In your conversation nodes' Conditions fields, you can check attributes such as:
Code: Select all
GetEnergyLevel("Harald") > 5;
Code: Select all
GetMood("Silvia") == 42;
Re: Custom Condition Control and Timeline
Hi,
wonderful, this is exactly what I'm looking for
Thank you!
wonderful, this is exactly what I'm looking for
Thank you!
Re: Custom Condition Control and Timeline
Happy to help!
Re: Custom Conditions - C# and Lua
Hi,
it's me again, I keep running into issues with Custom Conditions that call C# functions.
Quick summary: I have a condition that calls a boolean from a C# script but it chooses the "condition bool == true" path even though the condition is false.
(Warning: wall of text ahead....)
EDIT: I found the error before I even sent the message. I'm sending it anyways in case someone else has a similar issue. Yet, dear support person: If you have any ideas on how I could achieve my goal in a more elegant way- I appreciate any suggestions
Also: Do you have an answer for question 2 at the end of the text? It works just fine, I'm rather asking out of curiosity
What I want to have:
In the game some characters hesistate to speak to others due to various reasons. You (the player) can give them energy to overcome those impediments. If you start a conversation you get to read the thoughts of the character. Depending on how much energy the character has they either say the impediment text (e.g. "I'm afraid!") or its counterpart (e.g. "I'm afraid - but I should tell them anyways!"). In my example there are 3 impediments + counterparts.
(dialogue entries are structured as follows: start -> introduction -> imp 1 OR counterpart 1 -> imp 2 OR counterpart 2 -> imp 3 OR counterpart 3)
Each impediment has an individual energy-cost. The costs add up for each impediment and you have to pay the total cost to gain access to the respective counterparts.
Example:
imp 1 cost: 20 energy --> you need 20 energy in total
imp 2 cost: 50 energy --> you need 70 energy in total
imp 3 cost: 40 energy --> you need 110 energy in total
So far I used the following conditions which worked fine:
imp 1: GetEnergy("Harald") < 20
counterpart 1: GetEnergy("Harald") >= 20
imp 2: GetEnergy("Harald") < 70
counterpart 1: GetEnergy("Harald") >= 70
imp 3: GetEnergy("Harald") < 110
counterpart 3: GetEnergy("Harald") >= 110
However, I want to control those costs outside the dialogue database so if I want to change values later I don't have to go into each conversation and change (and calculate) them manually for each entry (there will be a LOT of dialogue).
What I did:
There's another script (Opportunity) that sits on a GameObject in the scene. The NPC GameObjects that are involved in the opportunity are children objects of the Opportunity-GameObject. Opportunity counts the dialogue entries that I marked as impediments using a custom field and creates an int[] of the respective length. I made this function available in editor: you press a button in the inspector, it calls initializeImpedimentArray, and you can assign the values for each impediment. This works fine.
My NPC has access to this array. A boolean (HasEnoughEnergy) compares the NPC's current energy to the energy cost values.
The dialogue manager has access to specific instances of the NPC script using the approach you suggested me earlier: It calls a function on an NPCLua script that sits on the Dialogue Manager GameObject in the scen and the NPCLua calls the NPC function with the given actor.
This is the code in NPCLua:
This is the code in my NPC script:
These are the conditions (in my example there are 3 impediments):
imp 1: GetHasEnoughEnergy("Harald", 0) == false
counterpart 1: GetHasEnoughEnergy("Harald", 0) == true
imp 2: GetHasEnoughEnergy("Harald", 1) == false
counterpart2: GetHasEnoughEnergy("Harald", 1) == true
imp 3: GetHasEnoughEnergy("Harald", 2) == false
counterpart 3: GetHasEnoughEnergy("Harald", 2) == true
The issue
The character starts with 0 energy. Still, when I start the conversation, it directly goes to counterpart 1, then continues with imp 2 and imp 3. In this example this should be the case when character.energy >= 20
The first dialogue entry (ID 1 - right after the 'Start' entry) has no conditions. It is an introduction to what the character is thinking about, and only then come the impediments.
Starting the conversation: It shows the introduction.
Console Output:
Harald (NPC) energy: 0 cost: 0 returning true
Harald (NPC) energy: 0 cost: 0 returning true
(--> it does not enter the for-loop in HasEnoughEnergy in NPC; --> is that why cost is 0? Also why does it call the function at all even though this dialoge entry does not have any conditions? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry)
Clicking "continue" first time: It shows counterpart 1 (should be impediment 1).
Console Output:
Harald (NPC) dialogueEntryIndex (input): 1 index: 1 i: 0 dialogueEntryIndex (input): 1 cost: 20 energy: 0
Harald (NPC) energy: 0 cost: 20 returning false
Harald (NPC) dialogueEntryIndex (input): 1 index: 1 i: 0 dialogueEntryIndex (input): 1 cost: 20 energy: 0
Harald (NPC) energy: 0 cost: 20 returning false
(--> dialogueEntryIndex (input) shouldn't it be 0? Also why does it enter the "condition = true" entry even though the function returns false? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so 1 is correct)
Clicking "continue" second time: It shows impediment 2.
Console Output:
Harald (NPC) dialogueEntryIndex (input): 2 index: 2 i: 0 dialogueEntryIndex (input): 2 cost: 20 energy: 0
Harald (NPC) dialogueEntryIndex (input): 2 index: 2 i: 1 dialogueEntryIndex (input): 2 cost: 70 energy: 0
Harald (NPC) energy: 0 cost: 70 returning false
(--> dialogueEntryIndex (input) shouldn't it be 1? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so 2 is correct)
Clicking "continue" third time: It shows impediment 3.
Console Output:
(--> shouldn't there be any output? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so the call for this condition already happened)
My questions are:
1: Where does it get the energy cost value "0" from? (values are not assigned at runtime - none of the values in the array is 0)
2: When entering imp2/counterpart2: Why does it only call the function once (There are 2 possible options - shouldn't it check all of them like it did before)?
3 (main question): It seems to me like there is an offset of 1 in the function calls (so conditions are already called on entering the previous dialogue entry). This worked fine with the conditions I used before (mentioned further up in the text). I think the error has to do with accessing the ImpedimentCosts Array. For some reason it returns a 0 value (and thus returns HasEnoughEnergy == true) which should not happen bc. there IS no 0 value.
Any ideas / suggestions / solutions?
I apologize for the massive amount of text that I threw at you. I appreciate any kind of help with this issue, any insight on the execution order of the condition calls or any suggestions of how I could handle the "energy costs" somewhere outside of the database in an easier, more elegant way (like I mentioned before - I'm not a total beginner to scripting but still quite a beginner ^^")
Thanks in advance!
lol, I found the error whilst writing down the issue: It's in the for loop in HasEnoughEnergy in my NPC script:
I wrote:
--> when it is called for the first time index = 0 so it doesn't enter the for loop and returns energy = 0.
It should be:
it's me again, I keep running into issues with Custom Conditions that call C# functions.
Quick summary: I have a condition that calls a boolean from a C# script but it chooses the "condition bool == true" path even though the condition is false.
(Warning: wall of text ahead....)
EDIT: I found the error before I even sent the message. I'm sending it anyways in case someone else has a similar issue. Yet, dear support person: If you have any ideas on how I could achieve my goal in a more elegant way- I appreciate any suggestions
Also: Do you have an answer for question 2 at the end of the text? It works just fine, I'm rather asking out of curiosity
What I want to have:
In the game some characters hesistate to speak to others due to various reasons. You (the player) can give them energy to overcome those impediments. If you start a conversation you get to read the thoughts of the character. Depending on how much energy the character has they either say the impediment text (e.g. "I'm afraid!") or its counterpart (e.g. "I'm afraid - but I should tell them anyways!"). In my example there are 3 impediments + counterparts.
(dialogue entries are structured as follows: start -> introduction -> imp 1 OR counterpart 1 -> imp 2 OR counterpart 2 -> imp 3 OR counterpart 3)
Each impediment has an individual energy-cost. The costs add up for each impediment and you have to pay the total cost to gain access to the respective counterparts.
Example:
imp 1 cost: 20 energy --> you need 20 energy in total
imp 2 cost: 50 energy --> you need 70 energy in total
imp 3 cost: 40 energy --> you need 110 energy in total
So far I used the following conditions which worked fine:
imp 1: GetEnergy("Harald") < 20
counterpart 1: GetEnergy("Harald") >= 20
imp 2: GetEnergy("Harald") < 70
counterpart 1: GetEnergy("Harald") >= 70
imp 3: GetEnergy("Harald") < 110
counterpart 3: GetEnergy("Harald") >= 110
However, I want to control those costs outside the dialogue database so if I want to change values later I don't have to go into each conversation and change (and calculate) them manually for each entry (there will be a LOT of dialogue).
What I did:
There's another script (Opportunity) that sits on a GameObject in the scene. The NPC GameObjects that are involved in the opportunity are children objects of the Opportunity-GameObject. Opportunity counts the dialogue entries that I marked as impediments using a custom field and creates an int[] of the respective length. I made this function available in editor: you press a button in the inspector, it calls initializeImpedimentArray, and you can assign the values for each impediment. This works fine.
Code: Select all
public int impedimentsCount()
{
int sum = 0;
//conversation = DialogueManager.MasterDatabase.GetConversation(conversationName); //copy pasted from Dialogue System Trigger -- might not work in editor, since master database is created during runtime?
conversation = dialogueDatabase.GetConversation(conversationName);
foreach (DialogueEntry entry in conversation.dialogueEntries)
{
if (Field.LookupValue(entry.fields, "IsImpediment") == "True")
{
sum += 1;
}
}
return sum;
}
public void initializeImpedimentArray() //Forum entry: https://www.pixelcrushers.com/phpbb/viewtopic.php?f=3&t=3737&p=20811&hilit=access+custom+field+by+code#p20811
{
impedimentCosts = new float[impedimentsCount()];
}
The dialogue manager has access to specific instances of the NPC script using the approach you suggested me earlier: It calls a function on an NPCLua script that sits on the Dialogue Manager GameObject in the scen and the NPCLua calls the NPC function with the given actor.
This is the code in NPCLua:
Code: Select all
public bool GetHasEnoughEnergy(string actorName, double impedimentIndex)
{
NPC npc = FindNPC(actorName);
if (npc != null)
{
//Debug.Log(this + " npc.HasEnoughEnergy(impedimentIndex): " + npc.HasEnoughEnergy(impedimentIndex));
return npc.HasEnoughEnergy(impedimentIndex);
}
else
{
Debug.Log(this + "npc = null, actorName: " + actorName);
return false;
}
}
Code: Select all
public bool HasEnoughEnergy(double impedimentIndex)
{
//int index = (int)dialogueEntryIndex;
int index = Mathf.RoundToInt((float)impedimentIndex); //convert double to int
//Debug.Log("dialogueEntryIndex: " + impedimentIndex + " index: " + index);
double cost = 0;
if (opportunity != null) //check if there is an Opportunity script attached to a parent
{
if (opportunity.impedimentCosts.Length > 0) //check if array has any values
{
for (int i = 0; i < index; i++) //energy cost ist checked in each dialogue entry and you need the complete amount of energy to make the character talk so all values up to the current dialogue entry are added together
{
cost += opportunity.impedimentCosts[i];
Debug.Log(this + " dialogueEntryIndex (input): " + impedimentIndex + " index: " + index + " i: " + i + " dialogueEntryIndex (input): " + impedimentIndex + " cost: " + cost + " energy: " + energy);
//Debug.Log(this + " energy: " + energy);
}
}
}
if(energy >= cost)
{
Debug.Log(this + " energy: " + energy + " cost: " + cost + " returning true");
return true;
}
else
{
Debug.Log(this + " energy: " + energy + " cost: " + cost + " returning false");
return false;
}
}
imp 1: GetHasEnoughEnergy("Harald", 0) == false
counterpart 1: GetHasEnoughEnergy("Harald", 0) == true
imp 2: GetHasEnoughEnergy("Harald", 1) == false
counterpart2: GetHasEnoughEnergy("Harald", 1) == true
imp 3: GetHasEnoughEnergy("Harald", 2) == false
counterpart 3: GetHasEnoughEnergy("Harald", 2) == true
The issue
The character starts with 0 energy. Still, when I start the conversation, it directly goes to counterpart 1, then continues with imp 2 and imp 3. In this example this should be the case when character.energy >= 20
The first dialogue entry (ID 1 - right after the 'Start' entry) has no conditions. It is an introduction to what the character is thinking about, and only then come the impediments.
Starting the conversation: It shows the introduction.
Console Output:
Harald (NPC) energy: 0 cost: 0 returning true
Harald (NPC) energy: 0 cost: 0 returning true
(--> it does not enter the for-loop in HasEnoughEnergy in NPC; --> is that why cost is 0? Also why does it call the function at all even though this dialoge entry does not have any conditions? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry)
Clicking "continue" first time: It shows counterpart 1 (should be impediment 1).
Console Output:
Harald (NPC) dialogueEntryIndex (input): 1 index: 1 i: 0 dialogueEntryIndex (input): 1 cost: 20 energy: 0
Harald (NPC) energy: 0 cost: 20 returning false
Harald (NPC) dialogueEntryIndex (input): 1 index: 1 i: 0 dialogueEntryIndex (input): 1 cost: 20 energy: 0
Harald (NPC) energy: 0 cost: 20 returning false
(--> dialogueEntryIndex (input) shouldn't it be 0? Also why does it enter the "condition = true" entry even though the function returns false? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so 1 is correct)
Clicking "continue" second time: It shows impediment 2.
Console Output:
Harald (NPC) dialogueEntryIndex (input): 2 index: 2 i: 0 dialogueEntryIndex (input): 2 cost: 20 energy: 0
Harald (NPC) dialogueEntryIndex (input): 2 index: 2 i: 1 dialogueEntryIndex (input): 2 cost: 70 energy: 0
Harald (NPC) energy: 0 cost: 70 returning false
(--> dialogueEntryIndex (input) shouldn't it be 1? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so 2 is correct)
Clicking "continue" third time: It shows impediment 3.
Console Output:
(--> shouldn't there be any output? edit after I found my error: I think I understand it now, apparently the conditions are already called in the previous entry, so the call for this condition already happened)
My questions are:
1: Where does it get the energy cost value "0" from? (values are not assigned at runtime - none of the values in the array is 0)
2: When entering imp2/counterpart2: Why does it only call the function once (There are 2 possible options - shouldn't it check all of them like it did before)?
3 (main question): It seems to me like there is an offset of 1 in the function calls (so conditions are already called on entering the previous dialogue entry). This worked fine with the conditions I used before (mentioned further up in the text). I think the error has to do with accessing the ImpedimentCosts Array. For some reason it returns a 0 value (and thus returns HasEnoughEnergy == true) which should not happen bc. there IS no 0 value.
Any ideas / suggestions / solutions?
I apologize for the massive amount of text that I threw at you. I appreciate any kind of help with this issue, any insight on the execution order of the condition calls or any suggestions of how I could handle the "energy costs" somewhere outside of the database in an easier, more elegant way (like I mentioned before - I'm not a total beginner to scripting but still quite a beginner ^^")
Thanks in advance!
lol, I found the error whilst writing down the issue: It's in the for loop in HasEnoughEnergy in my NPC script:
I wrote:
Code: Select all
or (int i = 0; i < index; i++)
It should be:
Code: Select all
or (int i = 0; i <= index; i++)
Re: Custom Condition Control and Timeline
Hi,
I think this all boils down to: Conversations Evaluate Conditions One Extra Level Ahead
You'll need to structure your conversations with this in mind.
I think this all boils down to: Conversations Evaluate Conditions One Extra Level Ahead
You'll need to structure your conversations with this in mind.
Re: Custom Condition Control and Timeline
Hi,
thanks for the documentation link, this is really helpful!
thanks for the documentation link, this is really helpful!
Re: Custom Condition Control and Timeline
Glad to help!