Is There A Way To Make If Statement Condition Shorter
I'm currently working with this if statement condition check and I'm wondering from a more experienced code person if this can be made more compact or if this is just the way it is supposed to be? It just seems to be a lot of redundant code is my only concern
if (KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "12. I am not ok" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "7. You just asked me that" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "8. I really don’t care to dignify that with an answer Michael" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "9. I’m afraid not" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "10. Obviously not" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "18. No Michael.18" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "29. No comment" ||
KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "39. No I’m afraid not") {
KITTvoiceBox.YouHadAlreadyAskedThatResp ();
}
Answer by joshuauhler · Nov 17, 2016 at 03:15 PM
You could make those strings into a List Object.
List<String> KITTvoiceBoxList = new List <String> {"12. I am not ok","7. You just asked me that",...};
if (KITTvoiceBoxList.Exists (x => x == KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name)) { KITTvoiceBox.YouHadAlreadyAskedThatResp (); }
This is compact but uses slightly more memory.
Using a list will also allow you to add new strings to it via code. So it can be dynamic and make it so you don't have to keep adding more ors in your if statement.
Answer by Cepheid · Nov 17, 2016 at 03:53 PM
@zentaiguy
Josuauhler's is suggestion is a really good one for compactness, although there is a slight increase in memory usage, although that increase is so negligible that it won't cause an issue at all.
If not, another way to condense long if statements and make them slightly faster is by using a switch-case. Using a switch-case your code would now look like the following:
switch(KITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name)
{
case "12. I am not ok":
case "7. You just asked me that":
case "8. I really don’t care to dignify that with an answer Michael":
case "9. I’m afraid not":
case "10. Obviously not":
case "18. No Michael.18":
case "29. No comment":
case "39. No I’m afraid not":
KITTvoiceBox.YouHadAlreadyAskedThatResp ();
break;
}
The code above is untested and quickly whipped together but that should do the job.
I was originally going to suggest this, but zentaiguy was looking for compactness. Personally I agree with you and would use a switch statement.
thanks @ Cepheid, I like that the only trouble is that I'm already using a switch case fro my initial voice response calls like this:
case "WhatDoYouThinkOfThis":
//Check if it Is $$anonymous$$ichael And That Shut Up $$anonymous$$ode Is OFF
//Lets Say you Already Asked $$anonymous$$.I.T.T. This
//$$anonymous$$ood Is Good
if ($$anonymous$$ITTmodesObject.is$$anonymous$$ichael == true && $$anonymous$$ITTmodesObject.$$anonymous$$oodIsGood == true && $$anonymous$$ITTmodesObject.Surveilance$$anonymous$$odeActive == false
&& $$anonymous$$ITTmodesObject.$$anonymous$$ITT_isSpeaking == false && $$anonymous$$ITTmodesObject.ShutUp$$anonymous$$ode == false) {
if ($$anonymous$$ITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "19. Interesting, should I scan the area" ||
$$anonymous$$ITTvoiceBox.GetComponent<VoiceBox> ().lastClipPlayed.name == "7. You just asked me that") {
$$anonymous$$ITTvoiceBox.YouHadAlreadyAskedThatResp ();
} else if (($$anonymous$$ITTmodesObject.is$$anonymous$$ichael == true) && ($$anonymous$$ITTmodesObject.$$anonymous$$ITT_isSpeaking == false) && ($$anonymous$$ITTmodesObject.ShutUp$$anonymous$$ode == false)) {
Debug.Log ("$$anonymous$$ichael Asked --- What Do You Think Of This?");
$$anonymous$$ITTvoiceBox.WhatDoYouThinkOfThisResp ();
//Positive So Add "1" point To The $$anonymous$$ood Level
$$anonymous$$ITTmodesObject.$$anonymous$$ITT_$$anonymous$$oodLevel++;
}
}
break;
In Fact I Wonder If maybe the best approach might be to check it on the voice response requests from the switch case? Similar to the way I'm doing it on the voicebox script side but ins$$anonymous$$d maybe something like making a variable in the switch case script like: public "__" lastQorA; The "Blank" being I'm not sure how to access this part from the public variable in the inspector:
case "WhatsWrongWithThisTown":
Answer by ThePersister · Nov 17, 2016 at 04:08 PM
[Upgraded Answer]
Hey @zentaiguy,
Looking at your comments I got an idea of what you're trying to do. I made a setup of what I would do with your goal in mind, in the hope of inspiring you and helping you on your way! :)
Visually (Also settable from code):
The Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class Dialogue : MonoBehaviour
{
[Header("Main")]
public List<Question> m_availableQuestions = new List<Question>();
public Response m_alreadyAskedResponse = new Response(); // Add audioclip "You already said that"
public Response m_silentResponse = new Response(); // Keep empty, and check for empty when trying to play the clip?
[Header("KITT")]
public KITT m_currentKITT = new KITT();
public Response AskRandomQuestion()
{
// Random Question.
Question randomQuestion = m_availableQuestions.GetRandom();
// Already asked.
if (randomQuestion.m_wasAlreadyAsked)
{
return m_alreadyAskedResponse;
}
else
{
randomQuestion.m_wasAlreadyAsked = true;
}
// Positive, Negative or Silent.
ResponseType responseType = m_currentKITT.GetResponseType(randomQuestion);
switch (responseType)
{
case ResponseType.Positive:
return randomQuestion.m_positiveResponses.GetRandom();
case ResponseType.Negative:
return randomQuestion.m_negativeResponses.GetRandom();
default:
return m_silentResponse; // Silent response is default.
}
}
}
[Serializable]
public class Question
{
// Putting the string as first item, makes it come up in the inspector as visual identifier in a list.
public string m_questionString = "";
public bool m_wasAlreadyAsked = false;
public List<KITTPerson> m_questionIsCompatibleWith = new List<KITTPerson>();
public List<Response> m_positiveResponses = new List<Response>();
public List<Response> m_negativeResponses = new List<Response>();
public Question()
{
// Compatible with all persons by default.
m_questionIsCompatibleWith.AddRange( (KITTPerson[]) Enum.GetValues(typeof(KITTPerson)));
}
}
[Serializable]
public class Response
{
public AudioClip m_responseClip;
// Add other data if necessary.
}
[Serializable]
public class KITT
{
[Range(1, 10)]
public int m_moodLevel = 6, // Mood from 1 to 10.
m_moodThreshold = 5; // When is mood good or bad.
public Mood m_currentMood = Mood.Good;
public ShutUpMode m_shutUpMode = ShutUpMode.Off;
public KITTPerson m_kittPerson = KITTPerson.Michael;
public ResponseType GetResponseType(Question question)
{
bool forMe = question.m_questionIsCompatibleWith.Contains(m_kittPerson);
if (m_shutUpMode == ShutUpMode.On)
{
return ResponseType.Silent;
}
else if (!forMe || m_currentMood == Mood.Bad)
{
_changeMoodLevel(-1);
return ResponseType.Negative;
}
else
{
_changeMoodLevel(1);
return ResponseType.Positive;
}
}
public void _changeMoodLevel(int difference)
{
m_moodLevel = Mathf.Clamp(m_moodLevel + difference, 1, 10);
m_currentMood = m_moodLevel >= m_moodThreshold ? Mood.Good : Mood.Bad;
}
}
public enum ResponseType
{
Silent,
Positive,
Negative
}
public enum KITTPerson
{
Michael,
Jimmy,
Ted
}
public enum ShutUpMode
{
On,
Off
}
public enum Mood
{
Good,
Bad
}
public static class ListExtension
{
public static T GetRandom<T>(this IList<T> list)
{
if (list == null)
{
throw new System.NullReferenceException("List is null, make sure the list was initialized with = new List<>() first.");
}
else if (list.Count == 0)
{
throw new System.IndexOutOfRangeException("Cannot select a random item from an empty list");
}
return list[UnityEngine.Random.Range(0, list.Count)];
}
}
I hope that helps, if it did, please accept this answer, it'd be much appreciated! If you need anything else, let me know!
Cheers,
ThePersister
Your answer works also, but what I am using is lambda not Linq.
You're right my bad! End of the day takes a toll on me, haha. Thank you for correcting me, I've updated the post.
Thanks @ThePersister, I'm wondering how something like that would fair as I have a HUGE multi array of voice responses I draw from depending on what is asked of $$anonymous$$ITT. Each question or statement usually has a varied response depending on what is in the array for that specific question or statement.
Your answer
Follow this Question
Related Questions
The If statement condition is false but the if statement stills executes 1 Answer
If an integer ends with an 1. 1 Answer
Add changeable conditions in the editor, similar to unityEvent? 0 Answers
SqrMagnitude intermittently doesn't work for if statement on prefab. (C sharp) 1 Answer
If statement for direction the character is facing 0 Answers