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 ();
}
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 (); }
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.
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!
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!