Unity- How to get a time instant? - ios

I'm trying to create a swipe function to work in iOS devices. I've calculated the start touch position and the end touch position. Now, I want to calculate the start time and end time to get a time difference between the two touch events.
I've tried Time.time and Time.deltatime but as You already know It didn't work. So Please Help. Or if have any better suggestions for swipe, then please suggest me.
Thank You.

I believe what brandon is implying is you need to record Time.time in a variable such as startTime where you detect start touch then where you are recording the end touch do something like:
diffTime = Time.time - startTime
EDIT: Based on your comment I'm assuming it didn't work. Without your code its hard to say where you're getting lost but I'll try a psuedo code example in C# (don't know whether you're using Boo, C#, or Javascript):
public class Example : MonoBehaviour {
public float startTime;
public float diffTime;
void Update() {
if (/* DETECT TOUCH START */ ) {
startTime = Time.time; // Record startTime in secs since game start.
}
if (/* DETECT TOUCH END */ ) {
diffTime = Time.time - startTime; // Record diffTime in secs since startTime.
Debug.Log("startTime / diffTime = " + startTime + " / " + diffTime);
startTime = 0; // Reset startTime.
}
}
}

Related

rails stimulus calculate time

I have a stimulus component that is supposed to calculate the time spent on a page. When loading it saves to a variable the start time and on the event turbo:before-cache it calculates Date.now()-start.
My approach kinda works but it always adds a couple more seconds to the real ones..
I just started with stimulus and I wonder if there's a better way of doing this
let startTime;
export default class extends Controller {
initialize(){
this.boundHandleMyEvent = this.handleMyEvent.bind(this);
}
connect() {
startTime = Date.now()
console.log("connect")
document.addEventListener('turbo:before-cache', this.boundHandleMyEvent);
}
disconnect() {
console.log("disconect")
document.removeEventListener('turbo:before-cache', this.boundHandleMyEvent);
}
handleMyEvent() {
fetch(`http://localhost:3002/time/?totalTime=${Date.now()-startTime}&startTime=${startTime}&endTime=${Date.now()}`)
}
```
Thanks

Swift: Triggering sound effects during a timer

I've created a super simple count down application. You press a button, and the count down runs. The end result calculating looks like this:
10.0
9.999
9.998
...
And each whole number represents a second, so as you can imagine it runs fast.
While this loop runs, I have code in it to play a sound if it finds the current values to be 3.0 or 2.0 or 1.0 or 0.0.
Everything triggers and the sound plays, however it is glitchy as heck. About 80% of the time is triggers perfectly. The rest of the time it is either delayed by a fraction of a second or misses it completely. The sound effects are critical to the app.
I've used prepare to play properly and it did nothing to improve. My current implementation is using SKTAudio which I feel like is a bit overkill for my needs.
Any advice?
Please mind one moment - if you are using Double class to compare two values, you may find, that 2.0 value is not real 2.0, but 2.0000000001 for example. So, 2 and 2.0000001 are different values and your sound will no be played
Use may try smth. like
let checkValue: Double = 2 // your comparison value
let timerValue = 2.00000001 //for example
if (timerValue - Double(Int(timerValue))) == 0 && checkValue == timerValue {
print("Cool")
} else {
print("Not cool")
}
or almost the same
let checkValue: Double = 2 // your comparison value
let timerValue = 2.00000001 //for example
if timerValue == Double(Int(timerValue)) && timerValue == checkValue {
print("Cool")
} else {
print("Not cool")
}

How to add a timer?

I have a working Unity script with multi-touch that will detect the touch, see if the touch has hit a collider (part of a gameObject), then checking to see if it is the right collider, and destroying it. Here is the working code:
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
void Update () // Updates every frame
{
if (Input.touchCount != 0) // Triggered by a touch
{
foreach (Touch touch in Input.touches) // Triggered as many times as there are touches.
{
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(touch.position), Vector2.zero);
if (hit && touch.phase == TouchPhase.Began && hit.collider.gameObject.tag ==("Fish")) // Triggered if touch hits something, when touch just begins, and if the object hit was tagged as a "Fish"
{
hit.collider.gameObject.GetComponent<FishScript>().TappedOut(); // Fish script activated
}
}
}
}
}
This is the working code. Now I want to add a timer in there, and I want it to time the touch. I want to make it so if the player can tap, and move their finger over the fish and it will count, so long as the moved their finger over the fish in 1 second. Here is the script I wrote and need help with:
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
void Update () // Updates every frame
{
if (Input.touchCount != 0) // Triggered by a touch
{
foreach (Touch touch in Input.touches) // Triggered as many times as there are touches.
{
if (touch.phase == TouchPhase.Began)
{
float touchTimer = Time.time;
int i = touch.fingerId;
}
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(touch.position), Vector2.zero);
if (hit && hit.collider.gameObject.tag ==("Fish")) // Triggered if touch hits something, when touch just begins, and if the object hit was tagged as a "Fish"
{
hit.collider.gameObject.GetComponent<FishScript>().TappedOut(); // Fish script activated
}
}
}
}
}
This is all I have so far. I tried using a return statement, and that did not work in the Void Update() function. I tried making another function with a while loop that would wait until each frame finished before going through another loop. That did not work. Will this idea work?
Here is a simple timer in Unity. Put CheckTimer() on your Update() method.
private double counter = 0.000d;
public double time = 2.000d; // How many seconds you want your timer to run
void CheckTimer()
{
counter+= Time.deltaTime;
if (counter >= time)
{
// Time has passed
counter = 0.000d;
// Do stuff here..
}
}
In your case, you may set a bool to true when your condition is met, then make it so that CheckTimer() only runs when the condition is true.
To fix this make the timer a global variable by instantiating it at the top and doing as follows
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
public float timer;
public float duration;
void Start(){
duration = 1; //you can set this in code or in your hierarchy in Unity
}
void Update () // Updates every frame
{
if (Input.touchCount != 0) // Triggered by a touch
{
foreach (Touch touch in Input.touches) // Triggered as many times as there are touches.
{
if (touch.phase == TouchPhase.Began)
{
timer = Time.time + duration;
}
if(Time.time < timer){
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(touch.position), Vector2.zero);
if (hit && hit.collider.gameObject.tag ==("Fish")) // Triggered if touch hits something, when touch just begins, and if the object hit was tagged as a "Fish"
{
hit.collider.gameObject.GetComponent<FishScript>().TappedOut(); // Fish script activated
}
}
}
}
}
}
I don't have the rest of your code to ensure this works but the logic behind it does. You want to set your timer to the current time plus a given duration. If the current time is less than the timer you have set when the player does something, then you know they did their action before the time reached the timer. Does that make sense?
I know I'm not suppose to take up comment spaces by saying thanks, but thanks Jonnus. The only thing that baffles me now is how I didn't think of this sooner. Anyways, here is the take away code for anybody who needs help with a multi-touch script.
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
Private float timer; // Control variable
Public float duration; // How long you want your touch to be valid
Void Start ()
{
duration = 1; // Also adjustable in the interface
}
Void Update ()
{
if (Input.touchCount != 0) // Triggered by a touch
{
Foreach (Touch touch in Input.touches) // Triggered as many times as there are touches
{
if (touch.phase == TouchPhase.Began)
{
timer = Time.time + duration;
}
RaycastHit2D objectPlayerTouched = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(touch.position), Vector2.zero);
// var objectPlayerTouched is the 2DCollider for whatever the player tapped on.
if (objectPlayerTouched != null && Time.time < timer) // Triggered if player taps an object and time is still valid
{
objectPlayerTouched(destroy); // This means whatever object the player tapped is now destroyed
}
}
}
}
Once again, a big thanks to Jonnus. I thought this would be a lot more complicated. Also, don't do what I did and forget to set the duration in the interface and end up spending 10 minutes looking for a problem... Trust me it's annoying.

How to make a timer keep running even if game enters background in cocos2d-x c++ game in ios

I am using a timer in my cocos2d-x game (c++) ios. I am using cocos2d-x 2.2 version.
My function for time is as follows
in my init
this->schedule(schedule_selector(HelloWorld::UpdateTimer), 1);
I have defined the function as follows.
void HelloWorld::UpdateTimer(float dt)
{
if(seconds<=0)
{
CCLOG("clock stopped");
CCString *str=CCString::createWithFormat("%d",seconds);
timer->setString(str->getCString());
this->unschedule(schedule_selector(HelloWorld::UpdateTimer));
}
else
{
CCString *str=CCString::createWithFormat("%d",seconds);
timer->setString(str->getCString());
seconds--;
}
}
Everythings is working fine. But i have this timer to keep running even if the game enters background state. I have tried commenting the body of didEnter Background in appdelegate but not successfull. Any help will be appreciated
Thanks
If the app gets in the background, apart from some special background threads, no other thread gets executed.
Best way for you would be to save the unix timestamp in a variable during didEnterBackground, and when app resumes, fetch the current unix timestamp and compare the delta, to get the total time passed and update your timer accordingly.
In my AppDelegate.cpp I wrote the following code in applicationDidEnterBackground function. Here I took a value of time in seconds whenever the app goes background and store it in a CCUserdefault key. And when the app comes to foreground I again took the local system time and subtracted that from the time I stored in the key. Following is my code
void AppDelegate::applicationDidEnterBackground()
{
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
CCLog("year------->%04d",timeinfo->tm_year+1900);
CCLog("month------->%02d",timeinfo->tm_mon+1);
CCLog("day------->%02d",timeinfo->tm_mday);
CCLog("hour------->%02d",timeinfo->tm_hour);
CCLog("minutes------->%02d",timeinfo->tm_min);
CCLog("seconds------->%02d",timeinfo->tm_sec);
int time_in_seconds=(timeinfo->tm_hour*60)+(timeinfo->tm_min*60)+timeinfo->tm_sec;
CCLOG("time in seconds is %d",time_in_seconds);
CCUserDefault *def=CCUserDefault::sharedUserDefault();
def->setIntegerForKey("time_from_background", time_in_seconds);
CCDirector::sharedDirector()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}
void AppDelegate::applicationWillEnterForeground()
{
CCUserDefault *def=CCUserDefault::sharedUserDefault();
int time1=def->getIntegerForKey("time_from_background");
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime (&rawtime);
CCLog("year------->%04d",timeinfo->tm_year+1900);
CCLog("month------->%02d",timeinfo->tm_mon+1);
CCLog("day------->%02d",timeinfo->tm_mday);
CCLog("hour------->%02d",timeinfo->tm_hour);
CCLog("mintus------->%02d",timeinfo->tm_min);
CCLog("seconds------->%02d",timeinfo->tm_sec);
int time_in_seconds=(timeinfo->tm_hour*60)+(timeinfo->tm_min*60)+timeinfo->tm_sec;
int resume_seconds= time_in_seconds-time1;
CCLOG("app after seconds == %d", resume_seconds);
CCDirector::sharedDirector()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}
You can see and calculate the time the app remained in background.

Control sound to only play once in XNA

I use a sound each time a key is pressed to fire a missile. But it doesn't sound nice. I guess it's because the the sound is repeated so many times while the key is pressed down and that the code is within the Update method. I'm looking for a simple solution to just play the sound once when key is pressed? (I have tested to use a boolean variable to be true the first time and then false after det the sound has been played, but this didn't worked well because, when and where should I set it to true again) Help is preciated!
// Fire
if (keyboardState.IsKeyDown(Keys.Space))
{
missile.launchMissile(spaceship.spaceshipPosition, spaceship.spaceshipDirection);
soundExplosion.Play();
}
EDIT New code that isn't working!?
KeyboardState keyboardState = Keyboard.GetState();
KeyboardState prevKeyboardState;
prevKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Space) && prevKeyboardState.IsKeyUp(Keys.Space))
{
missile.launchMissile(spaceship.spaceshipPosition, spaceship.spaceshipDirection);
soundExplosion.Play();
}
Store your previous keyboard state as well
KeyBoardState prevKeyboardState;
then in your update
prevKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Space) && prevKeyboardState.IsKeyUp(Keys.Space))
{
//your code
}
You're basically just triggering the sound tons of times every second making it sound awful.

Resources