0
\$\begingroup\$

I'm working on a medi-sci project where I want the patient to use brainwaves to exercise control the environment.

The environmnet is a 2D game where the game character is to be controlled by 2 flickering squares. Each square are supposed to be on different frequencies e.g. 7Hz and 9Hz. They should flicker between black and white.

These frequencies will be measured on the brain and used to move the characters in a BCI solution. The project is being made in Unity and in c#.

I tried to use the animator and the Update function in Unity to get a flickering but it didn't work out (Read: It was very bad) because when the game became slow so did the flickering. I couldn't use that.

A friend told me that there's a difference between CRT and LCD screens so the refresh rate is different and can't be used the same way. I was also told to look into Timer.Interval in C# (or just the Timer class) and use that to switch between black and white squares to get the right frequency.

Is there anyone who could show me how to do this the right way in unity with C#? I mean how can I use Timers.Interval or System.Timers.Timer (or something else in the Timer class) to give me the right frequency in Unity?

I would prefer an example because I can't see any way of getting to the solution at all...

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

First off CRT and LCD are different in may ways. Though I'm not sure how their refresh rate changes. I can say, with absolute certainty, that their difference in refresh systems is not something that is used. Nor is it something that you can change, or something that will be effected by game-code (aside from maybe adjusting the refresh rate, if you felt like going to an extreme.) All you can do is pump out an image to it though the cable connected to your computer, after that all you can do is hope the monitor displays it.

If your pumping out images to fast for the monitor to display them, then it drops the frame. If your pumping out images slower than it's displaying them, then it continues to display the same frame (for a brief time.)


There are two options that I'm seeing:

  1. http://docs.unity3d.com/ScriptReference/Time-deltaTime.html

Delta time indicates the number of seconds that have passed between this frame and the last frame. Since it's a float variable, you can use it to determine the amount of time that has lapsed for your Hz cycle. This, however, is frame-rate dependent. Granted, if your game is going around 9Hz (which would be 9fps), it's not going to be playable anyway. Typically, you want a minimum of 20Hz before a game is considered playable. 30Hz is standard. 60Hz is ideal (It's the refresh-rate of most modern monitors.)

  1. FixedUpdate() - http://docs.unity3d.com/Manual/class-TimeManager.html

FixedUpdate gets called every x.y seconds regardless of frame-rate (frame-rate might be sacrificed to ensure it.) Should be fairly reliable. You then have the problem, however, of if that frame gets rendered. Even if it updates, if your frame-rate is slow enough to skip an entire 9Hz cycle, you might not see it update. (But it will cycle regardless.)


HOWEVER, I personally would say to figure out why your frame-rate is dropping low enough to make it problematic. There should be diagnostic tools somewhere in unity, find your-self the bottlenecks and fix them. If the games becoming slow-enough to be visible in a 9Hz cycle, then it's a fairly major frame-rate drop.


Edit:

Okay, Here is the basic theory. You have Hz, Hz is a unit of measurement that records the number of cycles per second. So saying you want something to switch on and off at 9 Hz, means you want it to turn on and off 9 times a second.

So we need some way to express the on/off oscillation according to time. The easiest means of oscillation we have access to is a sine or cosine wave.

If we are to use that, we end up with a value that goes from 0, to 1, to 0, to -1, to 0...

However, we only need on and off. We don't need every value between -1 and 1. We can simplify it by saying "This half of the cycle means on, and this half of the cycle means off." To divide it into half, we'll use the value 0 as our switch point. Resulting in something like:

a rendering of a 3 Hz sine wave with the positive colored black, and the negative colored white

All this theory coming down to the code:

using UnityEngine;
using System.Collections;

public class flicker : MonoBehaviour
{
    public Sprite white;
    public Sprite black;
    public SpriteRenderer ren;
    public float cycleHz; // Hz, the mesurement of cycles.

    float dtime = 0; // delta time

    // Update is called once per frame
    void Update()
    {
        // update frequency time-step
        dtime += Time.deltaTime;

        // Sample the waveform at a specific time.
        float wave = Mathf.Sin( (dtime * 2.0f * Mathf.PI) * cycleHz);

        print (dtime);
        print (wave);

        // Cycle between sprites based on the waveform.
        if (wave > 0.0f)
        {
            print ("Black");
        }
        else
        {
            print ("White");
        }

        // prevents dtime from climbing to infinity,
        // by stepping it back in the waveform to a point
        // of equal value.
        if (wave == 0.0f)
        {
            dtime = 0.0f;
        }
    }
}

Bonus Fun:

  • What happens when we make it so that the switch point is 0.5?
  • What if it's cosine instead of sine?
  • What happens if we make it tangent instead of sine or cosine?
\$\endgroup\$
11
  • \$\begingroup\$ I tried FixedUpdate it didn't work out either. I tried a print out which showed it was impossible. The 9Hz is not for the whole game but for the flickering square. The lagging came from the gameobjects in the game. The main player is trying to catch elements dropping from the sky and if there are a bit too many the game starts to go slow for a few secs or more which means the flickering does too. This is the reason why I'm seeking another way which works (like the Timer class from c#...) and hopefully it would work. \$\endgroup\$ Commented Jul 6, 2014 at 14:29
  • \$\begingroup\$ So the flickering code, as you have it, works fine. It's just that the game slows down when you are drawing to many elements to the screen? \$\endgroup\$ Commented Jul 6, 2014 at 16:43
  • \$\begingroup\$ using UnityEngine; using System.Collections; public class flicker : MonoBehaviour { public Sprite white; public Sprite black; public SpriteRenderer ren; // Update is called once per frame void FixedUpdate () { if (ren.sprite == white) { ren.sprite = black; } else { ren.sprite = white; } } } \$\endgroup\$ Commented Jul 6, 2014 at 17:04
  • \$\begingroup\$ errr...dunno what happened above. Anyway that code is no go. One frequency and very simple code. Aye the game slows down. \$\endgroup\$ Commented Jul 6, 2014 at 17:07
  • \$\begingroup\$ The comments section doesn't accept newlines, but it kept the spaces for the indent, that's what happened there. Give me a few minutes, I need to work out the code an explanation as to why the code works, and why that code. You should look into how to prevent a mass of elements from lowering your frame-rate. \$\endgroup\$ Commented Jul 6, 2014 at 18:15
0
\$\begingroup\$

If you're not dead-set on flickering, there's a simple solution to this, which is to use a trig/wave method (like sin or cos). These will produce a continuous, even oscillation (which, at a high enough frequency, may appear similar to flickering).

I don't know enough about Unity to suggest why it didn't work. What I think is that you're probably using total game time (instead of time since the last draw/update call), or your update interval (since the last frame) is too big.

If you decide to use trigonometric functions, you can just use something like the current time (total number of seconds since game start or some other date/time) as the value to pass into the sine/cosine method.

\$\endgroup\$
2
  • \$\begingroup\$ I can't use trigonometric since I need a frequency I can set. So if I want a frequency on 6 hz I should be able to set that for the flickering squares and should get that output from the squares when I measure the brainwaves from the patient. \$\endgroup\$ Commented Jul 6, 2014 at 17:09
  • \$\begingroup\$ A frequency of 6hz means you iterate through 2pi * 6 every second. It shouldn't be hard to do that. \$\endgroup\$
    – ashes999
    Commented Jul 6, 2014 at 17:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .