How to put a time limit on a method in c# - c#

I want my player to give a speed boost for a few seconds. When it collects 4 items (paintCount = 4), the player gets a movement speed boost for a short period of time.
How do I code this time that my player moves faster?
I'm using c# and Unity.
using UnityEngine;
using System.Collections;
public class PowerUp : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
Paintser.SpeedUp();
Destroy(this.gameObject);
Paintser.paintCount++;
}
}
}
using UnityEngine;
using System.Collections;
public class Paintser : PowerUp
{
public static int paintCount = 0;
public int speedBoostTime = 3;
public static void SpeedUp()
{
if (paintCount == 4)
{
SimplePlayer0.speed = SimplePlayer0.speed * 2;
Paintser.paintCount = Paintser.paintCount = 0;
}
}
}

using UnityEngine;
using System.Collections;
public class Paintser : PowerUp
{
public float normalSpeed = 10;
public static int paintCount = 0;
public int speedBoostTime = 3;
public static void SpeedUp(){
SimplePlayer0.speed = SimplePlayer0.speed * 2;
Paintser.paintCount = Paintser.paintCount = 0;
StartCoroutine(duringBoost(speedBoostTime, normalSpeed));
}
private static IEnumerator duringBoost(int duration, int newSpeed){
yield return new WaitForSeconds(duration);
SimplePlayer0.speed = newSpeed;
}
}
}

A general idea should be:
Add this to the script of SimplePlayer0:
float speedBoostTime = 0;
void SpeedUp()
{
speed *= 2;
speedBoostTime = 3; // seconds
}
void Update()
{
while ( speedBoostTime > 0 )
{
speedBoostTime -= Time.deltaTime;
if ( speedBoostTime <= 0 ) speed /= 2;
}
}
And modify your code in this way:
public class Paintser : PowerUp
{
public static int paintCount = 0;
public int speedBoostTime = 3;
public static void SpeedUp()
{
if (paintCount == 4)
{
SimplePlayer0.SpeedUp();
Paintser.paintCount = Paintser.paintCount = 0;
}
}
}

Related

Farming game in C# cant fix level system

I am making a Farming game in Unity and I tried to implement an EXP System. I can not implement a function where you can plant a crop from an X player level.
This Code manages the whole farm
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FarmManager : MonoBehaviour
{
[Header("Money Settings")]
public PlantItem selectPlant;
public bool isPlanting = false;
public int money = 100;
public Text moneyTxt;
[Header("Button Color Settings")]
public Color buyColor = Color.green;
public Color cancelColor = Color.red;
public Color lockedColor = Color.grey;
[Header("Button Audio Settings")]
public AudioSource clickSound;
[Header("Cursor Settings")]
public Texture2D cursorArrow;
public Texture2D cursorPickaxe;
[Header("XP Settings")]
public int maxExp;
public float updatedExp;
public float plusXp;
public Image ExpBar;
public float expIncreasedPerSecond;
public int playerLevel;
public Text levelText;
public Text xpLevel;
// Start is called before the first frame update
void Start()
{
Cursor.SetCursor(cursorArrow, Vector2.zero, CursorMode.ForceSoftware);
moneyTxt.text = "$"+money;
playerLevel =1;
expIncreasedPerSecond =5f;
maxExp = 25;
updatedExp = 0;
plusXp = 0;
}
void Update () {
//updatedExp += expIncreasedPerSecond * Time.deltaTime;
ExpBar.fillAmount = updatedExp / maxExp;
levelText.text = playerLevel + "";
xpLevel.text = updatedExp + "/" + maxExp;
if (updatedExp >= maxExp)
{
plusXp = updatedExp-maxExp;
playerLevel++;
updatedExp=0+plusXp;
maxExp+=maxExp;
}
}
public void SelectPlant(PlantItem newPlant)
{
if(selectPlant == newPlant)
{
Debug.Log("Deselected" + selectPlant.plant.plantName);
selectPlant.btnImage.color = buyColor;
selectPlant.btnTxt.text = "Buy";
selectPlant = null;
isPlanting = false;
clickSound.Play();
}
else
{
if(selectPlant!=null)
{
selectPlant.btnImage.color = buyColor;
selectPlant.btnTxt.text = "Buy";
}
selectPlant = newPlant;
selectPlant.btnImage.color = cancelColor;
selectPlant.btnTxt.text = "Cancel";
Debug.Log("Selected" + selectPlant.plant.plantName);
isPlanting = true;
clickSound.Play();
}
}
public void Transaction(int value)
{
money+=value;
moneyTxt.text = "$"+money;
}
public void GiveXP (float value)
{
updatedExp += value;
}
}
And this is the code where I import the information from
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Plant", menuName ="Plant")]
public class PlantObject : ScriptableObject
{
[Header("Plant settings")]
public string plantName;
public Sprite[] plantStages;
public float timeBtwStages;
[Header("Money Settings")]
public int buyPrice;
public int sellPrice;
[Header("XP Settings")]
public int xpAmount;
public int levelNeeded;
[Header("Plant Icon")]
public Sprite icon;
}
I tried doing it this way, but it would not fix my issue and would not disable the crop until the needed level was reached and it gave me a ton of errors.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FarmManager : MonoBehaviour
{
[Header("Money Settings")]
public PlantItem selectPlant;
public bool isPlanting = false;
public int money = 100;
public Text moneyTxt;
[Header("Button Color Settings")]
public Color buyColor = Color.green;
public Color cancelColor = Color.red;
public Color lockedColor = Color.grey;
[Header("Button Audio Settings")]
public AudioSource clickSound;
[Header("Cursor Settings")]
public Texture2D cursorArrow;
public Texture2D cursorPickaxe;
[Header("XP Settings")]
public int maxExp;
public float updatedExp;
public float plusXp;
public Image ExpBar;
public float expIncreasedPerSecond;
public int playerLevel;
public Text levelText;
public Text xpLevel;
// Start is called before the first frame update
void Start()
{
Cursor.SetCursor(cursorArrow, Vector2.zero, CursorMode.ForceSoftware);
moneyTxt.text = "$"+money;
playerLevel =1;
expIncreasedPerSecond =5f;
maxExp = 25;
updatedExp = 0;
plusXp = 0;
}
void Update () {
//updatedExp += expIncreasedPerSecond * Time.deltaTime;
ExpBar.fillAmount = updatedExp / maxExp;
levelText.text = playerLevel + "";
xpLevel.text = updatedExp + "/" + maxExp;
if (updatedExp >= maxExp)
{
plusXp = updatedExp-maxExp;
playerLevel++;
updatedExp=0+plusXp;
maxExp+=maxExp;
}
}
public void SelectPlant(PlantItem newPlant)
{
if(selectPlant == newPlant)
{
Debug.Log("Deselected" + selectPlant.plant.plantName);
selectPlant.btnImage.color = buyColor;
selectPlant.btnTxt.text = "Buy";
selectPlant = null;
isPlanting = false;
clickSound.Play();
}
else
{
if(selectPlant!=null)
{
selectPlant.btnImage.color = buyColor;
selectPlant.btnTxt.text = "Buy";
}
selectPlant = newPlant;
selectPlant.btnImage.color = cancelColor;
selectPlant.btnTxt.text = "Cancel";
Debug.Log("Selected" + selectPlant.plant.plantName);
isPlanting = true;
clickSound.Play();
}
if (selectPlant.plant.levelNeeded > playerLevel)
{
selectPlant.btnImage.color = lockedColor;
}
}
public void Transaction(int value)
{
money+=value;
moneyTxt.text = "$"+money;
}
public void GiveXP (float value)
{
updatedExp += value;
}
}
I have been stuck on this for weeks now any ideas?

Destroy element when craft is complete Unity 3d c#

I have been making a game on Unity following the tutorial by Sykoo, this one.
And I have a problem with the crafting system, when I want the items to be destroyed when the craft is made, but I dont know how to do it. Can someone help me please?
here is the craft item script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class CraftableItem : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public GameObject thisItem;
public int requiredItems;
public GameObject[] item;
private bool hovered;
private GameObject player;
private GameObject itemManager;
public void Start()
{
player = GameObject.FindWithTag("Player");
itemManager = GameObject.FindWithTag("ItemManager");
}
public void Update()
{
if (hovered == true)
{
if(Input.GetMouseButtonDown(0))
{
CheckForRequiredItems();
}
}
}
public void CheckForRequiredItems()
{
int itemsInManager = itemManager.transform.childCount;
if (itemsInManager > 0)
{
int itemsFound = 0;
for(int i = 0; i < itemsInManager; i++)
{
for (int z = 0; z < requiredItems; z++)
{
if (itemManager.transform.GetChild(i).GetComponent<Item>().type == item[z].GetComponent<Item>().type)
{
itemsFound++;
break;
}
}
}
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
}
the inventory script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
//Instructions *correct
public GameObject inventory;
public GameObject slotHolder;
public GameObject itemManager;
private bool inventoryEnabled;
private int slots;
private Transform[] slot;
private GameObject itemPickedUp;
private bool itemAdded;
private GameObject player;
//Start *correct
public void Start()
{
// slots being detected
inventoryEnabled = true;
slots = slotHolder.transform.childCount;
slot = new Transform[slots];
DetectInventorySlots();
}
// Inventory GUI
public void Update()
{
if (Input.GetKeyDown(KeyCode.I))
{
inventoryEnabled = !inventoryEnabled;
}
if(inventoryEnabled)
{
inventory.GetComponent<Canvas>().enabled = true;
Time.timeScale = 0;
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
else
{
inventory.GetComponent<Canvas>().enabled = false;
Time.timeScale = 1;
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
}
// Inventory Pick *correct
public void OnTriggerStay(Collider other)
{
if (other.tag == "Item")
{
itemPickedUp = other.gameObject;
AddItem(itemPickedUp);
}
}
public void OnTriggerExit(Collider other)
{
if (other.tag == "Item")
{
itemAdded = false;
}
}
// Add Item *correct
public void AddItem(GameObject item)
{
for (int i = 0; i < slots; i++)
{
if (slot[i].GetComponent<Slot>().empty && itemAdded == false)
{
slot[i].GetComponent<Slot>().item = itemPickedUp;
slot[i].GetComponent<Slot>().itemIcon = itemPickedUp.GetComponent<Item>().icon;
//attachs the item to the hand *correct
item.transform.parent = itemManager.transform;
item.transform.position = itemManager.transform.position;
//equipar arma
item.transform.localPosition = item.GetComponent<Item>().position;
item.transform.localEulerAngles = item.GetComponent<Item>().rotation;
item.transform.localScale = item.GetComponent<Item>().scale;
Destroy(item.GetComponent<Rigidbody>());
itemAdded = true;
item.SetActive(false);
}
}
}
// Detect slots *correct
public void DetectInventorySlots()
{
for (int i = 0; i < slots; i++)
{
slot[i] = slotHolder.transform.GetChild(i);
}
inventory.GetComponent<Canvas>().enabled = true;
inventoryEnabled = false;
}
}
and the slot script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; // Required when using Event data.
using UnityEngine.UI;
public class Slot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
//instructions *correct
private bool hovered;
public bool empty;
public Image image;
public GameObject item;
public Texture itemIcon;
private GameObject player;
//Update *correct
void Start()
{
player = GameObject.FindWithTag("Player");
hovered = false;
image.enabled = false;
}
void Update()
{
if (item)
{
empty = false;
itemIcon = item.GetComponent<Item>().icon;
this.GetComponent<RawImage>().texture = itemIcon;
} else {
empty = true;
this.GetComponent<RawImage>().texture = null;
}
}
//Pointer *correct
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
public void OnPointerClick(PointerEventData eventData)
{
if(item)
{
Item thisItem = item.GetComponent<Item>();
//water
if(thisItem.type == "Water")
{
player.GetComponent<Player>().Drink(thisItem.decreaseRate);
Destroy(item);
}
//food
if (thisItem.type == "Food")
{
player.GetComponent<Player>().Eat(thisItem.decreaseRate);
Destroy(item);
}
//weapon
if(thisItem.type == "Weapon" && player.GetComponent<Player>().weaponEquipped == false)
{
thisItem.equipped = true;
item.SetActive(true);
imageEnabled();
}
if (thisItem.type == "Weapon" && player.GetComponent<Player>().weaponEquipped == true)
{
thisItem.equipped = false;
item.SetActive(false);
image.enabled = false;
player.GetComponent<Player>().weaponEquipped = false;
}
}
}
public void imageEnabled()
{
image.enabled = !image.enabled;
}
public class StackItem
{
public Item item = new Item();
public int amount = 1;
}
}
but i think you will only need the craft system script. Hope someone can help me.
Seems like your craft is completed on this instruction:
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
}
Next to GameObject spawndedItem... string you can specify your element deletion code, as an example:
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
Destroy(GameObject.Find("ObjectThatYouWantToDestroyName"));
}

Unity2D. Method "OnTriggerEnter2D" does not work on prefabs

I have one problem, I am not running the "OnTriggerEnter2D" method on the prefab.
I took the object, threw a script on it, added the right components and made it prefab.
I have a hero when he attacks a collider appears which is a trigger.
If this collider is a player's sword then the enemy receives damage.
A regular object (not a prefab) gets damaged, but if I do this object a prefab and drag it onto the stage then the "OnTriggerEnter2D" method does not work.
Here's the enemy script. I also poured my project on the Github, for a better understanding. I will be very grateful for the help, because I could not understand the reason. My project -
https://github.com/OleksandrKupchuk/SimpleGame
//Enemy Archer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyArcher : EnemyBase
{
[SerializeField] GameObject arrowPrefab;
[SerializeField] Transform startPositionArrow;
public override void Start()
{
base.Start();
ChangeStateEnemy(new IdleState());
}
public new void Update()
{
//ChangeState(currentState);
StateEnemy();
}
private void StateEnemy()
{
currentState.Execute();
}
public override void Attack()
{
timeAttack += Time.deltaTime;
enemyAnimator.SetFloat("animatorEnemyRun", 0);
if (timeAttack >= delayAttack)
{
CanAttack = true;
timeAttack = 0;
}
if (CanAttack)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
CanAttack = false;
}
}
public void FireArrow()
{
if (facingRight)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
GameObject arrow = Instantiate(arrowPrefab, startPositionArrow.position, Quaternion.identity);
arrow.GetComponent<EnemyArrowMove>().ArrowInitialization(Vector2.right);
}
else
{
GameObject arrow = Instantiate(arrowPrefab, startPositionArrow.position, Quaternion.Euler(new Vector3(0f, 180f, 0f)));
arrow.GetComponent<EnemyArrowMove>().ArrowInitialization(Vector2.left);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("PlayerSword"))
{
Debug.Log("Take");
TakeDamage();
EnemyTarget = collision.gameObject;
}
}
}
//////
//Enemy Base
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(BoxCollider2D))]
[RequireComponent(typeof(CircleCollider2D))]
public class EnemyBase : CharacterBase
{
public IStateEnemy currentState;
protected float timeAttack;
[SerializeField] protected float delayAttack;
public bool CanAttack { get; set; }
protected float dirPlayer;
public GameObject EnemyTarget { get; set; }
[SerializeField] protected float enemyRangeAttack;
[SerializeField] int experienceForTheEnemy;
public bool EnemyRangeAttack
{
get
{
if (EnemyTarget != null)
{
if (Vector2.Distance(EnemyTarget.transform.position, transform.position) <= enemyRangeAttack)
{
return true;
}
}
return false;
}
}
public bool EnemyOutsideEdge
{
get
{
if(transform.position.x >= rightEdge.position.x || transform.position.x <= leftEdge.position.x)
{
return true;
}
return false;
}
}
//edges for enemy
[SerializeField] protected Transform leftEdge;
[SerializeField] protected Transform rightEdge;
public bool EnemyDie
{
get
{
if(health <= 0)
{
return true;
}
return false;
}
}
[SerializeField] EdgeCollider2D enemySword;
[SerializeField] private Rigidbody2D enemyRigidbody;
public Rigidbody2D EnemyRigidbody { get => enemyRigidbody; set => enemyRigidbody = value; }
public Animator enemyAnimator;
[SerializeField] int takeDamage;
public bool EnemyAttack { get; set; }
public bool EnemyHit { get; set; }
protected float directionEnemy;
public override void Start()
{
base.Start();
enemyAnimator = GetComponent<Animator>();
}
public void Update()
{
}
public void TakeDamage()
{
if (!EnemyDie)
{
enemyAnimator.SetTrigger("animatorEnemyHit");
health -= takeDamage;
if (health <= 0)
{
enemyAnimator.SetTrigger("animatorEnemyDie");
Destroy(gameObject, 1.5f);
Player.PlayerInstance.AddIndicatorForPlayer(experienceForTheEnemy);
}
}
}
public void EnemySwordEnabled()
{
enemySword.enabled = true;
}
public void EnemySwordDisabled()
{
enemySword.enabled = false;
}
public void Flip()
{
//Debug.Log("Flip");
facingRight = !facingRight;
transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y);
//transform.Rotate(0f, 180f, 0f);
}
public void Walk()
{
if (!EnemyAttack && !EnemyDie && !EnemyHit)
{
if ((ChangeSide().x > 0 && transform.position.x < rightEdge.position.x) || (ChangeSide().x < 0 && transform.position.x > leftEdge.position.x))
{
enemyAnimator.SetFloat("animatorEnemyRun", 1);
transform.Translate(ChangeSide() * speed * Time.deltaTime);
}
}
}
public Vector2 ChangeSide()
{
if (facingRight)
{
return Vector2.right;
}
return Vector2.left;
}
public void ChangeDirection()
{
if (transform.position.x >= rightEdge.position.x || transform.position.x <= leftEdge.position.x)
{
Flip();
}
}
public void EnemyLookTarget()
{
if (!EnemyDie && EnemyTarget != null)
{
directionEnemy = EnemyTarget.transform.position.x - transform.position.x;
if (directionEnemy < 0 && facingRight || directionEnemy > 0 && !facingRight)
{
Flip();
}
}
}
public virtual void Attack()
{
timeAttack += Time.deltaTime;
//enemyAnimator.SetFloat("animatorEnemyRun", 0);
if (timeAttack >= delayAttack)
{
CanAttack = true;
timeAttack = 0;
}
if (CanAttack)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
CanAttack = false;
}
}
public void ChangeStateEnemy(IStateEnemy newState)
{
currentState = newState;
currentState.Enter(this);
}
}

Cannot serialize my game stats

Well i am trying to save my Game Stats using system serializable but i am not being able to do it i have two scripts one named "Stats" and another named "SaveLoad" in the "Stats" i have my serializables and in the "SaveLoad" i have my saving and loading script i followed the instructions here
https://gamedevelopment.tutsplus.com/tutorials/how-to-save-and-load-your-players-progress-in-unity--cms-20934
But since i am a begginer with this stuff and my seriazable data differs i am having issues on saving it.
My "Stats"
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Stats : MonoBehaviour {
public static int coins = 0;
public static int totalcoins = 0;
public static int score = 0;
public static int personalbest = 0;
public static float UmbrellaSpeed = 0.1f;
public static float currentumbdur = 500;
public static int CarrotSpawnRateLVL = 1;
public static float CarrotSpawnRate = 60f;
public static int CarrotSpawnRateUpgradeCost = 15;
public static int UmbrellaDurabilityLVL = 1;
public static float UmbrellaDurability = 500;
public static int UmbrellaDurabilityUpgradeCost = 30;
public static int UmbrellaSizeLVL = 1;
public static float UmbrellaSize = 0f;
public static int UmbrellaSizeUpgradeCost = 25;
public static int CarrotEffectLVL = 1;
public static float CarrotEffect = 20;
public static int CarrotEffectUpgradeCost = 25;
public static int HealthRegenLVL = 1;
public static float HealthRegenTime = 4f;
public static int HealthRegenCost = 100;
public static int BuyTreesCost = 250;
public static int Tree1Bought = 0;
public static float Tree1Size = 0;
public static int Tree1SizeLVL = 1;
public static int Tree1SizeUpgradeCost = 50;
public static int Tree2Bought = 0;
public static float Tree2Size = 0;
public static int Tree2SizeLVL = 1;
public static int Tree2SizeUpgradeCost = 50;
public static int Tree3Bought = 0;
public static float Tree3Size =0;
public static int Tree3SizeLVL = 1;
public static int Tree3SizeUpgradeCost = 50;
// Use this for initialization
void Start () {
InvokeRepeating ("AddCoins", 4.0f, 2.0f);
InvokeRepeating ("AddScore", 1.5f, 1.5f);
}
// Update is called once per frame
void Update () {
if (score > personalbest) {
personalbest = score;
}
//Debug.Log (" " + coins);
}
void AddCoins (){
if (BunnyScript.BunnyAlive == true) {
coins += 1;
}
}
void AddScore (){
if (BunnyScript.BunnyAlive == true) {
score += 1;
}
}
}
And my "SaveLoad" script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad {
public static List<Stats> savedGames = new List<Stats>();
public static void Save (){
savedGames.Add(Stats);
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd");
bf.Serialize(file, SaveLoad.savedGames);
file.Close();
}
public static void Load (){
if (File.Exists (Application.persistentDataPath + "/savedGames.gd")) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open);
SaveLoad.savedGames = (List<Stats>)bf.Deserialize(file);
file.Close();
}
}
}
You should not serialize a MonoBehaviour class for storing data, there is so much below that you cannot see in this type that it is just wrong.
Also, you have a list of stats object but it is only containing static value so all your Stats objects have same content.
using UnityEngine;
using System.Collections;
public class Stats : MonoBehaviour
{
StatContainer stats = new StatContainer();
// Use this for initialization
void Start () {
InvokeRepeating ("AddCoins", 4.0f, 2.0f);
InvokeRepeating ("AddScore", 1.5f, 1.5f);
}
// Update is called once per frame
void Update () {
this.stats.Update();
}
void AddCoins (){
stats.AddCoins();
}
void AddScore (){
stats.AddScore();
}
}
[Serializable]
public class StatContainer
{
public int coins = 0;
public int totalcoins = 0;
public int score = 0;
public int personalbest = 0;
public float UmbrellaSpeed = 0.1f;
public float currentumbdur = 500;
public int CarrotSpawnRateLVL = 1;
public float CarrotSpawnRate = 60f;
public int CarrotSpawnRateUpgradeCost = 15;
// and the rest
public void Update(){
if (statscore > personalbest) {
personalbest = score;
}
}
}
Now you can serialize the StatContainer in the same manner you were.
Because there is no static method anymore, each StatContainr on each Stats component is unique and not sharing anything with others.
And bonus, you can even perform unit test more easily with StatContainer, but that is another topic.

serializing an object in C#

I have a serializable class named DataSource:
namespace GraphLib
{
public struct cPoint
{
public float x;
public float y;
}
[Serializable]
public class DataSource
{
public delegate String OnDrawXAxisLabelEvent(DataSource src, int idx);
public delegate String OnDrawYAxisLabelEvent(DataSource src, float value);
public OnDrawXAxisLabelEvent OnRenderXAxisLabel = null;
public OnDrawYAxisLabelEvent OnRenderYAxisLabel = null;
private cPoint[] samples = null;
private int length = 0;
private String name = String.Empty;
private int downSample = 1;
private Color color = Color.Black;
public float VisibleDataRange_X = 0;
public float DY = 0;
public float YD0 = -200;
public float YD1 = 200;
public float Cur_YD0 = -200;
public float Cur_YD1 = 200;
public float grid_distance_y = 200; // grid distance in units ( draw a horizontal line every 200 units )
public float off_Y = 0;
public float grid_off_y = 0;
public bool yFlip = true;
public bool Active = true;
private bool YAutoScaleGraph = false;
private bool XAutoScaleGraph = false;
public float XAutoScaleOffset = 100;
public float CurGraphHeight = 1.0f;
public float CurGraphWidth = 1.0f;
public float InitialGraphHeight = 0;
public float InitialGraphWidth = 0;
public bool AutoScaleY
{
get
{
return YAutoScaleGraph;
}
set
{
YAutoScaleGraph = value;
}
}
public bool AutoScaleX
{
get
{
return XAutoScaleGraph;
}
set
{
XAutoScaleGraph = value;
}
}
public cPoint[] Samples
{
get
{
return samples;
}
set
{
samples = value;
length = samples.Length;
}
}
public float XMin
{
get
{
float x_min = float.MaxValue;
if (samples.Length > 0)
{
foreach (cPoint p in samples)
{
if (p.x < x_min) x_min=p.x;
}
}
return x_min;
}
}
public float XMax
{
get
{
float x_max = float.MinValue;
if (samples.Length > 0)
{
foreach (cPoint p in samples)
{
if (p.x > x_max) x_max = p.x;
}
}
return x_max;
}
}
public float YMin
{
get
{
float y_min = float.MaxValue;
if (samples.Length > 0)
{
foreach (cPoint p in samples)
{
if (p.y < y_min) y_min = p.y;
}
}
return y_min;
}
}
public float YMax
{
get
{
float y_max = float.MinValue;
if (samples.Length > 0)
{
foreach (cPoint p in samples)
{
if (p.y > y_max) y_max = p.y;
}
}
return y_max;
}
}
public void SetDisplayRangeY(float y_start, float y_end)
{
YD0 = y_start;
YD1 = y_end;
}
public void SetGridDistanceY( float grid_dist_y_units)
{
grid_distance_y = grid_dist_y_units;
}
public void SetGridOriginY( float off_y)
{
grid_off_y = off_y;
}
[Category("Properties")] // Take this out, and you will soon have problems with serialization;
[DefaultValue(typeof(string), "")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public String Name
{
get { return name; }
set { name = value; }
}
[Category("Properties")] // Take this out, and you will soon have problems with serialization;
[DefaultValue(typeof(Color), "")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color GraphColor
{
get { return color; }
set { color = value; }
}
[Category("Properties")] // Take this out, and you will soon have problems with serialization;
[DefaultValue(typeof(int), "0")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Length
{
get { return length; }
set
{
length = value;
if (length != 0)
{
samples = new cPoint[length];
}
else
{
// length is 0
if (samples != null)
{
samples = null;
}
}
}
}
[Category("Properties")] // Take this out, and you will soon have problems with serialization;
[DefaultValue(typeof(int), "1")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Downsampling
{
get { return downSample; }
set { downSample = value; }
}
}
}
and i want to serialize it in a form like this:
public partial class Form1 : Form
{
public GraphLib.PlotterDisplayEx display;
private void serialize()
{
System.IO.Stream TestFileStream = System.IO.File.Create(#"C:\Users\Public\Documents\test.txt");
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
serializer.Serialize(TestFileStream, display.DataSources[0]);
TestFileStream.Close();
}
not that DataSource class that i want to serialize in Form1, is one of the attributes in GraphLib.PlotterDisplayEx class
but when i run the program it gives me the following error:
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: Type 'KTK.Form1' in Assembly 'KTK, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
UPDATE
I updated the code for DataSource class.now it's complete code guys.
You probably didn't show the complete code of the DataSource class. It directly or indirectly holds a reference to an object of type KTK.Form1.
This might be through an event to which the form is subscribed.
In this case you probably don't want to serialize it an should mark it as NonSerialized:
[field:NonSerialized]
public event ...;
Now that you updated the question. Change
public OnDrawXAxisLabelEvent OnRenderXAxisLabel = null;
public OnDrawYAxisLabelEvent OnRenderYAxisLabel = null;
to
[NonSerialized]
public OnDrawXAxisLabelEvent OnRenderXAxisLabel;
[NonSerialized]
public OnDrawYAxisLabelEvent OnRenderYAxisLabel;
The delegates may hold references to non-serializable classes.

Categories