How to send a value from from one script to another on Unity - unity3d

I am having an issue with dealing with some values that I want to send to.
The thing is that I want the total value of the time transcurred after quitting the game. When the player logs in, that value is multiplied with the money. So if the player connects after 30 minutes, the player will earn the value of 30 minutes multiplied with the money. Worked with JSON Serialization, public static, and PlayerPrefs but nothing.
PlayerPrefs and Serialization seem working but it only records the time stored before storing. For example, if the player connects after 5 seconds then 20 seconds, the second time it gets the value of 5 seconds and not 20 seconds.
Script A:
public SaveManager save_manager;
public DateTime new_time, old_time;
public TimeSpan gold_reward_time;
public float current_boostValue_gameplay;
private float minutes_booster_gameplay;
private float seconds_booster_gameplay;
private bool is_stopped_booster_gameplay;
private void Start()
{
new_time = DateTime.Now;
old_time = DateTime.Parse(PlayerPrefs.GetString("timeData"));
gold_reward_time = new_time - old_time;
Get_sum_of_time_reward();
}
private void OnApplicationQuit()
{
Application.Quit();
Sum_of_time_passed();
PlayerPrefs.SetString("timeData", DateTime.Now.ToString());
}
public void Get_sum_of_time_reward()
{
double time_hour = Convert.ToDouble(gold_reward_time.Hours);
double time_minutes = Convert.ToDouble(gold_reward_time.Minutes);
double time_seconds = Convert.ToDouble(gold_reward_time.Seconds);
double sum_of_time_values = time_hour + time_minutes + time_seconds;
PlayerPrefs.SetString("totalRewardTime",sum_of_time_values.ToString());
}
Script B:
public void Calculate_time_as_gold()
{
string load_resident_menu_data = File.ReadAllText(Application.persistentDataPath + "/resident_menu_data.json");
resident_data = Json_helper.FromJson<Resident_menu_data>(load_resident_menu_data);
string load_automation_menu_data = File.ReadAllText(Application.persistentDataPath + "/automation_menu_data.json");
automation_data = Json_helper.FromJson<Automation_menu_data>(load_automation_menu_data);
sum_of_all_per_sec = resident_data[0].resident_gold_per_sec + automation_data[0].automation_gold_per_sec;
sum_of_time_passed = double.Parse(PlayerPrefs.GetString("totalRewardTime"));
result_reward_after_time = sum_of_all_per_sec * sum_of_time_passed;
Debug.Log("total value 1 = " + double.Parse(PlayerPrefs.GetString("RewardTimeValue")));
reward_gold_text.text = Math.Truncate(result_reward_after_time).ToString();
}

PlayerPrefs.Save says you don't need to call it manually in OnApplicationQuit. Good.
Call Application.Quit(); at last in OnApplicationQuit. Otherwise your changes may not be saved I guess.
If you save the time like this: double sum_of_time_values = time_hour + time_minutes + time_seconds; wouldn't 20 minutes look the same as 20 seconds?
Why not simply add the Time.deltaTime in Update() to a variable? Time will be in seconds.

Related

How would I apply slowness effect to player without Coroutines

A few days ago I started a new project, a MOBA like test, and it is been going well for the most part. Currently I am having difficulties importing slowness effect or buff/debuff system in to the game. The exact problem is with the timer I need to change the speed value of the character but I can not use ref/out parameters in coroutines. I tried some other things like using invoke or using functions but they just do not do what I want. All feedback is appreciated and thanks in advance
Here is the code:
Coroutine:
public IEnumerator ApplyDebuff(ref float stat, float percentage, float duration)
{
float originalValue = stat;
float timeStamp = Time.time;
while (Time.time < timeStamp + duration)
{
float debuffValue = percentage / 100 * originalValue;
stat -= debuffValue;
yield return null;
}
stat = originalValue;
}
Where I call the coroutine
private void CheckForCollision()
{
Collider[] colliders = Physics.OverlapSphere(position, scale, layerMask);
foreach(Collider c in colliders)
{
c.TryGetComponent<PlayerController>(out PlayerController player);
player.ApplyDebuff(ref player.speed, 70, 5);
player.TakeDamage(50);
Destroy(gameObject);
}
}
You can't use ref in IEnumerator, the Action<float> solves the problem. This method is called Callback.
public IEnumerator ApplyDebuff(float stat, float percentage, float duration, Action<float> OnWhileAction, Action<float> AfterWaitAction)
{
float originalValue = stat;
float timeStamp = Time.time;
while (Time.time < timeStamp + duration)
{
float debufValue = percentage / 100 * originalValue;
OnWhileAction(debufValue);
yield return null;
}
AfterWaitAction(originalValue);
}
The following lambda can execute your command after wait simply.
foreach(Collider c in colliders)
{
/// ...
player.ApplyDebuff(player.speed, 70, 5, debufValue => player.speed-=debufValue, orginalValue => player.speed = orginalValue);
///...
}
For using System library as write using system in top of code;

day/night cycle and also track days?

I'm trying to make a day and night cycle that also keeps track of how many days passed. I watched a tutorial to start and for this post, I removed all the unnecessary stuff like rotating the sun and changing colors.
public class TimeController : MonoBehaviour
{
[SerializeField]
private float timeMultiplier;
[SerializeField]
private float startHour;
private DateTime currentTime;
void Start()
{
currentTime = DateTime.Now.Date + TimeSpan.FromHours(startHour);
}
void Update()
{
UpdateTimeOfDay();
}
private void UpdateTimeOfDay()
{
currentTime = currentTime.AddSeconds(Time.deltaTime * timeMultiplier);
}
}
The biggest issue I have with this is instead of timeMultiplier I'd rather have like a dayLength variable which represents how long a day should last in minutes so one day is 10minutes int dayLength = 600; or something like that, but I'm not sure how I'd implement that.
Also, I tried adding a method for checking if a day has passed, but the code ended up running like 20 times.
public int currentDay = 1;
private void HasDayPassed()
{
if (currentTime.Hour == 0)
{
Debug.Log("New day");
currentDay++;
}
}
Try this code
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimeController : MonoBehaviour
{
public const float SecondsInDay = 86400f;
[SerializeField] [Range(0, SecondsInDay)] private float _realtimeDayLength = 60;
[SerializeField] private float _startHour;
private DateTime _currentTime;
private DateTime _lastDayTime;
private int _currentDay = 1;
private void Start()
{
_currentTime = DateTime.Now + TimeSpan.FromHours(_startHour);
_lastDayTime = _currentTime;
}
private void Update()
{
// Calculate a seconds step that we need to add to the current time
float secondsStep = SecondsInDay / _realtimeDayLength * Time.deltaTime;
_currentTime = _currentTime.AddSeconds(secondsStep);
// Check and increment the days passed
TimeSpan difference = _currentTime - _lastDayTime;
if(difference.TotalSeconds >= SecondsInDay)
{
_lastDayTime = _currentTime;
_currentDay++;
}
// Next do your animation stuff
AnimateSun();
}
private void AnimateSun()
{
// Animate sun however you want
}
}
Also you can remove the range attribute to specify more slower day than the realtime day.

How to store System.currentTimeMillis() in an array with a park time simulator

I'm trying to store the time in milliseconds for every time this time park is executed. And then I would like to use HdrHistogram to represent the latency.
However, i can't store the times in my array. Please, could you provide any help?
public class PracticeLatency1
{
public static void main(String [] args)
{
int[] startTimes;
long startTime;
int index=0;
startTimes = new int[10000];
startTime = System.currentTimeMillis();
runCalculations();
startTimes[index++] = (int) (System.currentTimeMillis() - startTime);
System.out.println(startTimes);
}
/**
* Run the practice calculations
*/
// System.currentTimeMillis()
private static void runCalculations()
{
// Create a random park time simulator
BaseSyncOpSimulator syncOpSimulator = new SyncOpSimulRndPark(TimeUnit.NANOSECONDS.toNanos(100),
TimeUnit.MICROSECONDS.toNanos(100));
// Execute the operation lot of times
for(int i = 0; i < 10000; i++)
{
syncOpSimulator.executeOp();
}
// TODO Show the percentile distribution of the latency calculation of each executeOp call
}
}

Unity-Press Button to slowly increment number

I'm trying to do something like the old GTA style money system like in Gta vice city or san andreas. So when you add or obtain money, the number doesn't just jump to the result. It slowly increments till the value added is done.
I want to do this by clicking buttons, so one button will add 100 dollars and other will subtract 100 dollars and so on.
The buttons don't seem to be playing nice with update and Time.deltatime.
To slowly increment a number over the time, you can do something like this:
public float money = 100;
public int moneyPerSecond = 25;
public int moneyToReach = 100;
bool addingMoney = false;
private void Update()
{
if (addingMoney)
{
if (money < moneyToReach)
{
money += moneyPerSecond * Time.deltaTime;
}
else { addingMoney = false; money = Mathf.RoundToInt(money); }
}
}
public void addMoney()
{
moneyToReach += 100;
addingMoney = true;
}

Time Based Scoring Unity

Hi I'm a beginner in unity and I want to be able to add 10 points to the score every 5 seconds since the game started, this is how i tried to implement it
private int score;
void Update () {
Timer = Time.time;
if (Timer > 5f) {
score += 5;
Timer -= 5f;
}
ScoreText.text = score.ToString ();
}
this is not working what happens is the score increases rapidly after 5f and then it crashes my game.
The math for calculating every 5 seconds is wrong. You should not be doing Timer = Time.time; every loop, that just throws away the old value of Timer. Use Time.deltaTime and add it to the timer instead.
//Be sure to assign this a value in the designer.
public Text ScoreText;
private int timer;
private int score;
void Update () {
timer += Time.deltaTime;
if (timer > 5f) {
score += 5;
//We only need to update the text if the score changed.
ScoreText.text = score.ToString();
//Reset the timer to 0.
timer = 0;
}
}
I know I am a bit late to answer, but the same can be done with Mathf.FloorToInt(Time.timeSinceLevelLoad)