NeuroSky Mindwave Music Visualizer with Unity - c#

I'm working on a final project for school (art school not computer science) where I'd like to make a live visualizer from brainwaves using a NeuroSky Mindwave brain reader and Unity. Unfortunately the teacher has very limited knowledge of coding as well and has left me in a very bad position...
I've built a music visualizer following this tutorial:
https://www.youtube.com/watch?v=ELLANEFw5B8
And also found an example Unity project which can live read and display raw data from the brainwave reader:
https://github.com/tgraupmann/unity_neurosky
Where I'm stuck is in trying to change the input of my visualizer to be the raw brainwave data rather than music.
Is someone able to help me move forward with this project? I've already looked at NeuroSky's Unity integration page and emailed them with no success.
Any help will be greatly appreciated, thanks so much!
Audio Spectrum Visualizer Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spectrum : MonoBehaviour {
// Use this for initialization
public GameObject prefab;
public int numberOfObjects = 20;
public float radius = 5f;
public GameObject[] cubes;
void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
float angle = i * Mathf.PI * 2 / numberOfObjects;
Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
cubes = GameObject.FindGameObjectsWithTag ("cubes");
}
// Update is called once per frame
void Update () {
float[] spectrum = AudioListener.GetSpectrumData (1024, 0, FFTWindow.Hamming);
for(int i = 0; i < numberOfObjects; i++)
{
Vector3 previousScale = cubes[i].transform.localScale;
previousScale.y = Mathf.Lerp (previousScale.y, spectrum[i] * 40, Time.deltaTime * 30);
cubes[i].transform.localScale = previousScale;
}
}
}
ThinkGear Connector Controller Code
(as far as I know the file that causes the raw data to be displayed in Unity like the screenshot commented below)
using System;
using System.Threading;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using MindWave.LitJson;
using System.Net.Sockets;
using System.Text;
using System.IO;
namespace MindWave
{
public class TGCConnectionController : MonoBehaviour
{
private TcpClient client;
private Stream stream;
private byte[] buffer;
public delegate void UpdateIntValueDelegate(int value);
public delegate void UpdateFloatValueDelegate(float value);
public event UpdateIntValueDelegate UpdatePoorSignalEvent;
public event UpdateIntValueDelegate UpdateAttentionEvent;
public event UpdateIntValueDelegate UpdateMeditationEvent;
public event UpdateIntValueDelegate UpdateRawdataEvent;
public event UpdateIntValueDelegate UpdateBlinkEvent;
public event UpdateFloatValueDelegate UpdateDeltaEvent;
public event UpdateFloatValueDelegate UpdateThetaEvent;
public event UpdateFloatValueDelegate UpdateLowAlphaEvent;
public event UpdateFloatValueDelegate UpdateHighAlphaEvent;
public event UpdateFloatValueDelegate UpdateLowBetaEvent;
public event UpdateFloatValueDelegate UpdateHighBetaEvent;
public event UpdateFloatValueDelegate UpdateLowGammaEvent;
public event UpdateFloatValueDelegate UpdateHighGammaEvent;
private bool m_waitForExit = true;
private void Start()
{
ThreadStart ts = new ThreadStart(Connect);
Thread thread = new Thread(ts);
thread.Start();
}
public void Disconnect()
{
stream.Close();
}
public void Connect()
{
client = new TcpClient("127.0.0.1", 13854);
stream = client.GetStream();
buffer = new byte[1024];
byte[] myWriteBuffer = Encoding.ASCII.GetBytes(#"{""enableRawOutput"": true, ""format"": ""Json""}");
stream.Write(myWriteBuffer, 0, myWriteBuffer.Length);
while (m_waitForExit)
{
ParseData();
Thread.Sleep(100);
}
}
public class PowerData
{
public float delta = 0;
public float theta = 0;
public float lowAlpha = 0;
public float highAlpha = 0;
public float lowBeta = 0;
public float highBeta = 0;
public float lowGamma = 0;
public float highGamma = 0;
public PowerData()
{
}
}
public class SenseData
{
public int attention = 0;
public int meditation = 0;
public PowerData eegPower = null;
public SenseData()
{
}
}
public class PackatData
{
public string status = string.Empty;
public int poorSignalLevel = 0;
public int rawEeg = 0;
public int blinkStrength = 0;
public SenseData eSense = null;
public PackatData()
{
}
}
int GetObjectCount(String json)
{
int level = 0;
int count = 0;
for (int i = 0; i < json.Length; ++i)
{
if (json[i].Equals('{'))
{
if (level == 0)
{
++count;
}
++level;
}
if (json[i].Equals('}'))
{
--level;
}
}
return count;
}
private void ParseData()
{
if (stream.CanRead)
{
try
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
List<PackatData> packets = new List<PackatData>();
String packet = Encoding.ASCII.GetString(buffer, 0, bytesRead);
if (!string.IsNullOrEmpty(packet))
{
Debug.Log(packet);
if (packet.Contains("}"))
{
int count = GetObjectCount(packet);
if (count == 1)
{
PackatData data = JsonMapper.ToObject<PackatData>(packet);
packets.Add(data);
}
else if (count > 1)
{
PackatData[] data = JsonMapper.ToObject<PackatData[]>(packet);
for (int index = 0; index < data.Length; ++index)
{
packets.Add(data[index]);
}
}
}
}
foreach (PackatData data in packets)
{
if (null == data)
{
continue;
}
if (data.poorSignalLevel != 0)
{
Debug.Log("data.poorSignalLevel: " + data.poorSignalLevel);
if (null != UpdatePoorSignalEvent)
{
UpdatePoorSignalEvent.Invoke(data.poorSignalLevel);
}
if (null != data.eSense)
{
if (UpdateAttentionEvent != null)
{
UpdateAttentionEvent(data.eSense.attention);
}
if (UpdateMeditationEvent != null)
{
UpdateMeditationEvent(data.eSense.meditation);
}
if (null != data.eSense.eegPower)
{
if (UpdateDeltaEvent != null)
{
UpdateDeltaEvent(data.eSense.eegPower.delta);
}
if (UpdateThetaEvent != null)
{
UpdateThetaEvent(data.eSense.eegPower.theta);
}
if (UpdateLowAlphaEvent != null)
{
UpdateLowAlphaEvent(data.eSense.eegPower.lowAlpha);
}
if (UpdateHighAlphaEvent != null)
{
UpdateHighAlphaEvent(data.eSense.eegPower.highAlpha);
}
if (UpdateLowBetaEvent != null)
{
UpdateLowBetaEvent(data.eSense.eegPower.lowBeta);
}
if (UpdateHighBetaEvent != null)
{
UpdateHighBetaEvent(data.eSense.eegPower.highBeta);
}
if (UpdateLowGammaEvent != null)
{
UpdateLowGammaEvent(data.eSense.eegPower.lowGamma);
}
if (UpdateHighGammaEvent != null)
{
UpdateHighGammaEvent(data.eSense.eegPower.highGamma);
}
}
}
}
else if (data.rawEeg != 0)
{
if (null != UpdateRawdataEvent)
{
UpdateRawdataEvent(data.rawEeg);
}
}
else if (data.blinkStrength != 0)
{
if (null != UpdateRawdataEvent)
{
UpdateBlinkEvent(data.blinkStrength);
}
}
}
}
catch (IOException e)
{
Debug.Log("IOException " + e);
}
catch (System.Exception e)
{
Debug.Log("Exception " + e);
}
}
} // end ParseData
void OnDisable()
{
m_waitForExit = false;
Disconnect();
}
private void OnApplicationQuit()
{
m_waitForExit = false;
Disconnect();
}
}
}

I think you missed the signal processing natural of this problem. Brainwave (if it's Beta wave) has relatively low frequency range, which is about 15 Hz to 30 Hz. Music, on the other hand is audible tone, whose frequency range is between 20 Hz to 20,000 Hz.
I am not familiar with the implementation of this particular visualizer you mentioned here, but if it's implemented as what visualizer suppose to do, the brainwave should show only show some small activity (depends on the amplitude of the brainwave signal) in the lowest frequency range in the spectrum.
There is a potential hack to fix the problem. Usually a visualizer will use FFT to transform a time series signal to its frequency domain, during which it will determine the frequency range the operation is performed over. If you can locate the code in the visualizer and change the frequency range to, say 1 Hz to 100 Hz, you should see a proper frequency spectrum.

Related

Exclude items in an array in unity 2021

I've begun working on an early alpha menu for my game and I've was wondering how to exclude items in an array, specifically in unity. I'm trying to make every item except the currently used one. I don't know how I should go about it, if anyone could help, that would be amazing.
here's my current code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class CS
{
public List<GameObject> CanvasButtons;
}
public class CanvasSwitcher : MonoBehaviour
{
public List<CS> Screen = new List<CS>();
static int switcher;
public static void ScreenSwitchPlus()
{
switcher += 1;
}
public static void ScreenSwitchMinus()
{
switcher -= 1;
}
public void Update()
{
foreach(GameObject l in Screen[switcher].CanvasButtons)
{
l.SetActive(true);
}
}
}
It would be wiser to use for loop instead of foreach loop here:
public void Update()
{
int ignore = 2;
for(int i = 0; i < Screen[switcher].CanvasButtons.Count; i++)
{
if(i != ignore)
Screen[switcher].CanvasButtons[i].SetActive(true);
else
Screen[switcher].CanvasButtons[i].SetActive(false);
}
}
It could be even shorter without if (admit less readable):
public void Update()
{
int ignore = 2;
for(int i = 0; i < Screen[switcher].CanvasButtons.Count; i++)
{
Screen[switcher].CanvasButtons[i].SetActive(i != ignore);
}
}
... and even shorter with taking CanvasButtons out of loop:
public void Update()
{
int ignore = 2;
var collection = Screen[switcher].CanvasButtons;
for(int i = 0; i < collection.Count; i++)
{
collection[i].SetActive(i != ignore);
}
}
I got it! I was a bit null-brained for a while there, I messed up a few values in the second for statement, but I got it. I'll post the code here. I keep forgetting little things in the math. Like I always say, I don't solve problems, I make them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class CS
{
public List<GameObject> CanvasButtons;
}
public class CanvasSwitcher : MonoBehaviour
{
public List<CS> Screen = new List<CS>();
static int switcher;
public static void ScreenSwitchPlus()
{
switcher += 1;
}
public static void ScreenSwitchMinus()
{
switcher -= 1;
}
public void FixedUpdate()
{
List<CS> csco = Screen;
for(int i1 = 0; i1 < csco.Count;)
{
List<GameObject> collection = csco[i1].CanvasButtons;
for (int i = 0; i < collection.Count; i++)
{
collection[i].SetActive(i1 == switcher);
switch(i == collection.Count - 1)
{
case true:
i1++;
break;
}
}
}
}
}
I think you are making things too complicated.
It could simply be
public void Update()
{
for(var i = 0; i < Screen.Count; i++)
{
foreach(var button in Screen[i].CanvasButtons)
{
button.SetActive(i == switcher);
}
}
}
Two more points though.
First I would make sure that switcher is actually a valid value. You either want to clamp the value to stay within the index range like
public static void ScreenSwitchPlus()
{
switcher = Mathf.Clamp(switcher + 1, 0, Screen.Count);
}
public static void ScreenSwitchMinus()
{
switcher = Mathf.Clamp(switcher - 1, 0, Screen.Count);
}
or you could implement wrap around at the ends according to your needs like
public static void ScreenSwitchPlus()
{
switcher = (switcher + 1) % Screen.Count;
}
public static void ScreenSwitchMinus()
{
switcher -= 1;
if(switcher < 0) switcher = Screen.Count - 1;
}
and then finally as mentioned I wouldn't do this poll fetching the value in Update every frame at all but rather event driven.
If you really need to (I would claim it is just lazyness ;) ) have that value and methods static you could attach to an event like
private static event Action<int> OnSwitcherChanged;
public static void ScreenSwitchPlus()
{
switcher = (switcher + 1) % Screen.Count;
OnSwitcherChanged?.Invoke(switcher);
}
public static void ScreenSwitchMinus()
{
switcher -= 1;
if(switcher < 0) switcher = Screen.Count - 1;
OnSwitcherChanged?.Invoke(switcher);
}
and then listen to that event like
private void OnEnable()
{
OnSwitcherChanged += HandleSwitchChanged;
}
private void OnDisable()
{
OnSwitcherChanged -= HandleSwitchChanged;
}
private void HandleSwitchChanged(int newIndex)
{
for(var i = 0; i < Screen.Count; i++)
{
foreach(var button in Screen[i].CanvasButtons)
{
button.SetActive(i == switcher);
}
}
}
Try this
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class CS {
public List<GameObject> CanvasButtons;
}
public class CanvasSwitcher : MonoBehaviour {
public List<CS> Screen = new List<CS>();
private static bool m_changed = false;
private static int m_lastSwitcher = 0;
private static int m_switcher = 0;
static int switcher {
get {
return m_switcher;
}
set {
if ( switcher != value ) {
m_lastSwitcher = m_switcher;
m_changed = true;
m_switcher = value;
}
}
}
public static void ScreenSwitchPlus() {
switcher += 1;
}
public static void ScreenSwitchMinus() {
switcher -= 1;
}
private void Update() {
if ( m_changed ) {
UpdateCS();
m_changed = false;
}
}
void UpdateCS() {
if ( m_lastSwitcher < Screen.Count ) {
var canvasBtns = Screen[ m_lastSwitcher ].CanvasButtons;
for ( int i = 0; i < canvasBtns.Count; i++ ) {
canvasBtns[ i ].SetActive( false );
}
}
if ( switcher < Screen.Count ) {
var canvasBtns = Screen[ switcher ].CanvasButtons;
for ( int i = 0; i < canvasBtns.Count; i++ ) {
canvasBtns[ i ].SetActive( true );
}
}
}
}

How to get random int values to a prefab which is called multiple times(without repeating same value)?

I have created a prefab which contains text (a*b=) and input field (to get user's answer). and I am calling this prefab 5 times using c# script. I have assigned a & b to random.range(1,10) so i can get 5 different sums. but in my case i am getting same values to all 5 sums.
I tried foreach loop and it is getting random numbers out of given range and on clicking check button it shows even correct answers in red(as incorrect).
This is the first time i am dealing with calling prefab multiple times via script. so need some help to solve it please.
TestModeQuestionUI.cs
using Helper.Keyboard;
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TestModeQuestionUI : MonoBehaviour
{
internal RectTransform refRectTransform;
[SerializeField]
TextMeshProUGUI valueA; // valueB;
[SerializeField]
MyInputField AnswerInputField;
internal int id;
internal Action<TestModeQuestionUI> onSubmitValueOfInputFieldAction;
internal Action<TestModeQuestionUI> onSelectInputFieldAction;
Color defaultColorOfAnswer = new Color(0.19f, 0.19f, 0.19f, 1f);
Color correctColorOfAnswer = new Color(0f, 0.44f, 0f, 1f);
Color incorrectColorOfAnswer = new Color(1f, 0f, 0f, 1f);
public static TestModeQuestionUI curSelectedAnswerInputField;
//-------------------------------------------------------------------------
void Awake()
{
refRectTransform = GetComponent<RectTransform>();
}
private void SetNextAnswerInputFieldAsSelected(TestModeQuestionUI
curSelectedAnswerInputField)
{
throw new NotImplementedException();
}
public void SetQuestionLabel(string v)
{
valueA.text = v;
}
public void ActiveAnswerInputField(bool active)
{
AnswerInputField.gameObject.SetActive(active);
}
public int GetAnswerInputField()
{
int result = -1;
int.TryParse(AnswerInputField.textComponent.text, out result);
return result;
}
public void SetAnswerInputField(string msg)
{
AnswerInputField.textComponent.text = msg;
}
public void SelectAnswerInputField()
{
DeSelectCurSelectedAnswerInputField();
AnswerInputField.ActivateInputField();
curSelectedAnswerInputField = this;
}
public static void DeSelectCurSelectedAnswerInputField()
{
if (curSelectedAnswerInputField != null)
{
curSelectedAnswerInputField.AnswerInputField.DeactivateInputField();
}
curSelectedAnswerInputField = null;
}
public void SetResultOfAnswerInputField(int result)
{
switch (result)
{
//==================================
// Default Color For Answer Has Not Checked
case 0:
AnswerInputField.textComponent.color = defaultColorOfAnswer;
break;
//==================================
// Correct Color For Answer Has Checked Correct
case 1:
AnswerInputField.textComponent.color = correctColorOfAnswer;
break;
//==================================
// Incorrect Color For Answer Has Checked Incorrect
case 2:
AnswerInputField.textComponent.color = incorrectColorOfAnswer;
break;
}
}
public void OnSelectInputField()
{
//Debug.Log("On Select : " + id);
if (curSelectedAnswerInputField != this)
DeSelectCurSelectedAnswerInputField();
curSelectedAnswerInputField = this;
if (onSelectInputFieldAction != null)
onSelectInputFieldAction(this);
}
public void OnSubmitValueOfInputField()
{
if (onSubmitValueOfInputFieldAction != null)
onSubmitValueOfInputFieldAction(this);
}
}
TestModeManager.cs
public class TestModeManager : MonoBehaviour
{
public static TestModeManager instance;
[SerializeField]
GameObject refTestModeQuestionExampleParent;
[SerializeField]
GameObject refTestModeQuestionExamplePrefab;
[SerializeField]
GameObject checkButton;
[SerializeField]
GameObject nextButton;
private int a, b;
List<TestModeQuestionUI> testModeQuestionExampleList;
void Start()
{
CreateUI();
}
void Update()
{
#if UNITY_EDITOR
if (Input.GetKeyDown(KeyCode.KeypadEnter))
{ SetNextAnswerInputFieldAsSelected(TestModeQuestionUI.curSelectedAnswerInputField);
}
#endif
if (Input.GetKeyDown(KeyCode.Escape))
{
if (Keyboard.instance.gameObject.activeInHierarchy)
Keyboard.Close();
else
Application.Quit();
}
}
void CreateUI()
{
GameObject _GO;
TestModeQuestionUI _TestModeQuestionUIRefrence;
if (testModeQuestionExampleList == null)
testModeQuestionExampleList = new List<TestModeQuestionUI>();
// a = UnityEngine.Random.Range(1, 20);
// b = UnityEngine.Random.Range(1, 10);
for (int id = 1; id <= 5; id++)
{
_GO = Instantiate(refTestModeQuestionExamplePrefab,
refTestModeQuestionExampleParent.transform);
_GO.name = "TestModeQuestion Example " + id;
_TestModeQuestionUIRefrence = _GO.GetComponent<TestModeQuestionUI>
();
_TestModeQuestionUIRefrence.id = id;
_TestModeQuestionUIRefrence.onSubmitValueOfInputFieldAction =
SetNextAnswerInputFieldAsSelected;
testModeQuestionExampleList.Add(_TestModeQuestionUIRefrence);
}
ResetUI();
}
void ResetUI()
{
// Reset Multiplication Examples
a = UnityEngine.Random.Range(1, 10);
b = UnityEngine.Random.Range(1, 10);
foreach (TestModeQuestionUI _TestModeQuestionUIRefrence in
testModeQuestionExampleList)
{
_TestModeQuestionUIRefrence.SetQuestionLabel(a + " " + b + " = ");
//loop to get 5 different sums
var questions = GameObject.FindGameObjectsWithTag("question");
foreach (var question in questions)
{
// a++;
//b++;
}
}
//==================================
// Set First Answer Input Field As Selected
SetNextAnswerInputFieldAsSelected();
}
void SetNextAnswerInputFieldAsSelected(TestModeQuestionUI _
TestModeQuestionUIRefrence = null)
{
if (_TestModeQuestionUIRefrence == null)
{
//==================================
// Get First Input Field And Set As Selected
_TestModeQuestionUIRefrence = GettestModeQuestionExampleList(1);
if (_TestModeQuestionUIRefrence != null)
_TestModeQuestionUIRefrence.SelectAnswerInputField();
}
else
{
//==================================
// Get Next Input Field And Set As Selected
_TestModeQuestionUIRefrence =
GettestModeQuestionExampleList(_TestModeQuestionUIRefrence.id + 1);
if (_TestModeQuestionUIRefrence != null)
_TestModeQuestionUIRefrence.SelectAnswerInputField();
else
{
Keyboard.Close();
StartCoroutine(highlighCheckButton());
}
}
}
TestModeQuestionUI GettestModeQuestionExampleList(int id)
{
foreach (TestModeQuestionUI _TestModeQuestionUIRefrence in
testModeQuestionExampleList)
{
if (_TestModeQuestionUIRefrence.id == id)
{
return _TestModeQuestionUIRefrence;
}
}
return null;
}
IEnumerator EnableKeyboardAfterSometime(float time)
{
yield return new WaitForSeconds(time);
Keyboard.Open();
}
IEnumerator highlighCheckButton()
{
checkButton.transform.localScale = new Vector3(1f, 1f, 1f);
float animtionTime = 0.3f;
float scaleUpTo = 1.2f;
for (int i = 0; i < 4; i++)
{
yield return AnimationController.animate(scaleCheckButton,
animtionTime, 1f, scaleUpTo);
yield return AnimationController.animate(scaleCheckButton,
animtionTime, scaleUpTo, 1f);
}
checkButton.transform.localScale = new Vector3(1f, 1f, 1f);
}
void scaleCheckButton(float value)
{
checkButton.transform.localScale = new Vector3(value, value, value);
}
public void CheckButton()
{
int answer;
foreach (TestModeQuestionUI _TestModeQuestionUIRefrence in
testModeQuestionExampleList)
{
answer = _TestModeQuestionUIRefrence.GetAnswerInputField();
if ((a * b) == answer)
{
_TestModeQuestionUIRefrence.SetResultOfAnswerInputField(1);
}
else
{
_TestModeQuestionUIRefrence.SetResultOfAnswerInputField(2);
}
}
checkButton.SetActive(false);
nextButton.SetActive(true);
}
public void NextButton()
{
ResetUI();
nextButton.SetActive(false);
}
You should get the random value inside the loop, otherwise you get the same values.
foreach (TestModeQuestionUI _TestModeQuestionUIRefrence in testModeQuestionExampleList)
{
int a = UnityEngine.Random.Range(1, 10);
int b = UnityEngine.Random.Range(1, 10);
_TestModeQuestionUIRefrence.SetQuestionLabel(a, b);
}
You also should save a and b in TestModeQuestionUI because they are different betweent instances.
public class TestModeQuestionUI : MonoBehaviour
{
private int a, b;
public void SetQuestionLabel(int a, int b)
{
this.a = a;
this.b = b;
valueA.text = a + " " + b + " = ";
}
}
You have a lot of UI stuff but if i were you and if i do not want to get duplicates i would create a separate script for getting random values like this:
public class RandomIntegers {
private static List<int> myNumbersA = new List<int>();
private static List<int> myNumbersB = new List<int>();
public static void RandomValues(out int a,out int b)
{
if (myNumbersA.Count == 0)
{
for (int i = 0; i < 10; i++)
{
myNumbersA.Add(i + 1);
myNumbersB.Add(i + 1);
}
}
int indexA = Random.Range(0, myNumbersA.Count);
int indexB = Random.Range(0, myNumbersB.Count);
a = myNumbersA[indexA];
b = myNumbersB[indexB];
myNumbersA.RemoveAt(indexA);
myNumbersB.RemoveAt(indexB);
}
}
Then in your ResetUI function you can call this function using
RandomIntegers.RandomValues(out a,out b); The reason why i implemented it this way is instances of your prefab can access it when they are instantiated and since it is static you will not get same random results for a and b. But lets say you might get 6 for a and 8 for b but also 8 for a and 6 for b both will result as 48 at the end.

The member `System.Collections.Generic.List<BasePlayer>.Count' cannot be used as method or delegate

Here is some of my Code for a plugin on a game, if anyone could help it would be greatly appreciated.
namespace Oxide.Plugins
{
[Info("Fake Player Add Plugin", "NOT asmr", 0.0)]
class FakePlayerAddPlugin : CSharpPlugin
{
public int MaximumFakePlayer = 50; //if server has more than x legit players, dont add fakes.
public int PlayerFakeAdd = 43; //how many fake players to add
public float PlayerCheckDelay = 120f; //how often to check for player changes in seconds
void Loaded()
{
Puts("FakePlayerAddPlugin Loaded!");
}
float lasttime = 0f;
void OnFrame(float delta)
{
if (lasttime + PlayerCheckDelay > Time.realtimeSinceStartup) return;
lasttime = Time.realtimeSinceStartup;
var pcount = BasePlayer.activePlayerList?.Count(n => n.IsValid()) ?? 0;
var fcount = BasePlayer.activePlayerList?.Count(n => n == null) ?? 0;
if (pcount >= MaximumFakePlayer)
{
RemoveFakePlayers();
return;
}
if (PlayerFakeAdd > 0 && fcount != PlayerFakeAdd)
{
RemoveFakePlayers();
AddFakePlayers(PlayerFakeAdd);
}
}
public void RemoveFakePlayers()
{
BasePlayer.activePlayerList.RemoveAll(n => n == null);
}
public void AddFakePlayers(int amount)
{
for (int i = 0; i < amount; i++)
{
BasePlayer.activePlayerList.Add(null);
}
}
}
}
"The member `System.Collections.Generic.List.Count' cannot be used as method or delegate" is what I am getting back.

Issue in Unity, NullReferenceException: Object reference not set to an instance of an object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
thanks for reading, I am working on a small memory card game in C# using Unity. When I run a certain scene I am receiving constant errors.
The errors are as follows:
"NullReferenceException: Object reference not set to an instance of an object
Card.SetUpArt () (at Assets/Scripts/Card.cs:31)
Pairs.SetUpDeck () (at Assets/Scripts/Pairs.cs:62)
Pairs.Update () (at Assets/Scripts/Pairs.cs:23)"
My code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
public class Card : MonoBehaviour {
public static bool NO_TURN = false;
[SerializeField]
private int cardState; //state of card
[SerializeField]
private int cardNumber; //Card value (1-13)
[SerializeField]
private bool _setUp = false;
private Sprite cBack; //card back (Green square)
private Sprite cFace; //card face (1-10 JQKA)
private GameObject pairsManager;
void Begin()
{
cardState = 1; //cards face down
pairsManager = GameObject.FindGameObjectWithTag("PairsManager");
}
public void SetUpArt()
{
cBack = pairsManager.GetComponent<Pairs>().GetBack(); //<--error
cFace = pairsManager.GetComponent<Pairs>().GetFace(cardNumber);
turnCard();//turns the card
}
public void turnCard() //handles turning of card
{
if (cardState == 0)
{
cardState = 1;
}
else if(cardState == 1)
{
cardState = 0;
}
if (cardState == 0 && !NO_TURN)
{
GetComponent<Image>().sprite = cBack; // shows card back
}
else if (cardState == 1 && !NO_TURN)
{
GetComponent<Image>().sprite = cFace; // shows card front
}
}
//setters and getters
public int Number
{
get {return cardNumber;}
set { cardNumber = value;}
}
public int State
{
get { return cardState; }
set { cardState = value; }
}
public bool SetUp
{
get { return _setUp; }
set { _setUp = value; }
}
public void PairCheck()
{
StartCoroutine(pause ());
}
IEnumerator pause()
{
yield return new WaitForSeconds(1);
if (cardState == 0)
{
GetComponent<Image>().sprite = cBack;
}
else if (cardState == 1)
{
GetComponent<Image>().sprite = cFace;
}
}
}
And:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine;
public class Pairs : MonoBehaviour {
public Sprite[] cardFace; //array of card faces
public Sprite cardBack;
public GameObject[] deck; //array of deck
public Text pairsCount;
private bool deckSetUp = false;
private int pairsLeft = 13;
// Update is called once per frame
void Update () {
if (!deckSetUp)
{
SetUpDeck();
}
if (Input.GetMouseButtonUp(0)) //detects left click
{
CheckDeck();
}
}//Update
void SetUpDeck()
{
for(int i = 0; i <deck.Length; i++)//resets cards
{
deck[i].GetComponent<Card>().SetUp = false;
}
for (int ix = 0; ix < 2; ix++) //sets up cards twice,
{
for(int i = 1; i < 14; i++)//sets up card value (2-10 JQKA)
{
bool test = false;
int val = 0;
while (!test)
{
val = Random.Range(0, deck.Length);
test = !(deck[val].GetComponent<Card>().SetUp);
}//while
//sets up cards
deck[val].GetComponent<Card>().Number = i;
deck[val].GetComponent<Card>().SetUp = true;
}//nested for
}//for
foreach (GameObject crd in deck)
{
crd.GetComponent<Card>().SetUpArt();
}
if (!deckSetUp)
{
deckSetUp = true;
}
}//SetUpDeck
public Sprite GetBack()
{
return cardBack;
}//getBack
public Sprite GetFace(int i)
{
return cardFace[i - 1];
}//getFace
void CheckDeck()
{
List < int > crd = new List<int>();
for(int i = 0; i < deck.Length; i++)
{
if(deck[i].GetComponent<Card>().State == 1)
{
crd.Add(i);
}
}
if(crd.Count == 2)
{
CompareCards(crd);
}
}//CheckDeck
void CompareCards(List<int> crd)
{
Card.NO_TURN = true; //stops cards turning
int x = 0;
if(deck[crd[0]].GetComponent<Card>().Number ==
deck[crd[1]].GetComponent<Card>().Number)
{
x = 2;
pairsLeft--;
pairsCount.text = "PAIRS REMAINING: " + pairsLeft;
if(pairsLeft == 0) // goes to home screen when game has been won
{
SceneManager.LoadScene("Home");
}
}
for(int j = 0; j < crd.Count; j++)
{
deck[crd[j]].GetComponent<Card>().State = x;
deck[crd[j]].GetComponent<Card>().PairCheck();
}
}//CompareCards
}
Any help anyone can offer would be greatly appreciated. Thank you in advance.
Link to GitHub Repository
I don't have knowledge about C#, as I'm working with java. You should initialize your variables. For more information I found this link What is a NullReferenceException, and how do I fix it?

no overload for method 'Play' takes 0 arguments, more context

Im not really sure whats wrong, I'm pretty inexperienced with C#, and i posted this with everyone saying there isn't enough context, so Im posting the whole script. It isn't that long though, I just need this help!
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(AudioSource))]
public class MusicPlayer : MonoBehaviour {
public GUISkin skin;
public Song[] playlist;
public AudioClip mlgSong;
public AudioSource fastSource;
int currentSongID;
bool isPlaying;
[System.NonSerialized]
public bool fastMode = false;
string currentSongCredits;
//Song credits
float timer = 0;
float slidePosition;
float slidePositionMax = 20;
void Start() {
slidePosition = slidePositionMax;
ShuffleSongs();
audio.clip = playlist[0].clip;
currentSongID = 0;
isPlaying = audio.isPlaying;
if (!GameSettings.music) {
fastSource.Stop();
}
}
void Update() {
if ((!audio.isPlaying || GameSettings.keybinds.GetKeyDown("nextsong")) && isPlaying) {
if (currentSongID<playlist.Length-1) {
currentSongID++;
} else {
currentSongID = 0;
}
audio.clip = playlist[currentSongID].clip;
slidePosition = slidePositionMax;
Play (); //The error is here...
}
if ((!audio.isPlaying || GameSettings.keybinds.GetKeyDown("lastsong")) && isPlaying) {
if (currentSongID<playlist.Length+1) {
currentSongID++;
} else {
currentSongID = playlist.Length;
}
audio.clip = playlist[currentSongID].clip;
slidePosition = slidePositionMax;
Play (); //The error is also here.
}
//Timer
if (timer > 0) {
timer -= Time.deltaTime;
}
if (fastMode && fastSource.volume < 1) {
fastSource.volume = Mathf.Min(1,fastSource.volume + Time.deltaTime * 0.25f);
audio.volume = 0.5f - fastSource.volume/2;
}
if (!fastMode && fastSource.volume > 0) {
fastSource.volume = Mathf.Max(0,fastSource.volume - Time.deltaTime * 0.5f);
audio.volume = 0.5f - fastSource.volume/2;
}
if (timer > 0) {
slidePosition = Mathf.Lerp(slidePosition,0,Time.deltaTime);
} else {
slidePosition = Mathf.Lerp(slidePosition,slidePositionMax,Time.deltaTime);
}
}
public void Pause() {
Play (playlist[currentSongID].name);
}
public void Play(string credits) {
currentSongCredits = "Now playing: " + credits;
if (FindObjectOfType<MlgMode>() != null) {//IS MLG MODE
audio.clip = mlgSong;
currentSongCredits = "Now playing: xXxSW3GST3PxXx";
FindObjectOfType<MlgMode>().StartTheShit();//Start the wubs
}
isPlaying = true;
if (!audio.mute) {
timer = 8;
}
audio.Play();
}
void OnGUI() {
if (slidePosition < slidePositionMax-0.1f) {
GUI.skin = skin;
GUIStyle style = new GUIStyle(GUI.skin.label);
style.fontSize = 16;
style.alignment = TextAnchor.MiddleRight;
Rect rect = new Rect(0,Screen.height-30+slidePosition,Screen.width,30);
//GUIX.ShadowLabel(rect,currentSongCredits,style,1);
GUILayout.BeginArea(rect);
GUILayout.FlexibleSpace (); //Push down
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace(); //Push to the right
GUILayout.Label(currentSongCredits,GUI.skin.GetStyle("SoundCredits"),GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
GUILayout.EndArea();
}
}
void ShuffleSongs() {
//Shuffle playlist using Fisher-Yates algorithm
for (int i = playlist.Length;i > 1;i--) {
int j = Random.Range(0,i);
Song tmp = playlist[j];
playlist[j] = playlist[i - 1];
playlist[i - 1] = tmp;
}
}
}
[System.Serializable]
public class Song {
public string name;
public AudioClip clip;
}
Your Play method is declared like this:
public void Play(string credits)
but you are calling it like this:
Play();
You need to include a string as a parameter when you call it.
Play("White and Nerdy - Weird Al Yankovic");
Your Play(string credits) method is expecting a string called credits. Since you call Play() without putting a string there, it is giving you an error.
What it is looking for is an overloaded method, another form of Play() without the string and when it doesn't find that you receive that error.

Categories

Resources