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?
Related
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"));
}
I am using a free joystick pack off the unity asset store that I am modifying. I am using touch fields along with the joys sticks to control the player movement and looking. Everything works just fine in unity itself, however when i build it out to my android phone, the very first time i interact with the joysticks they move around and reposition just fine as i drag around. After this first interaction with them however they no longer reposition as I drag and I am stumped.
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class FixedTouchField : MonoBehaviour, IPointerDownHandler, IPointerUpHandler,
IDragHandler
{
[HideInInspector]
public Vector2 TouchDist;
[HideInInspector]
public Vector2 PointerOld;
[HideInInspector]
protected int PointerId;
[HideInInspector]
public bool Pressed;
public FixedJoystick joystick;
public Image joystickHandle;
private float timeTakenDuringLerp = 1.0f;
private float timeStartedLerping;
void Update()
{
if (Pressed)
{
float timeSinceStarted = Time.time - timeStartedLerping;
float percentageComplete = timeSinceStarted / timeTakenDuringLerp;
joystick.GetComponent<Image>().color = Color.Lerp(new Color(1,1,1,0), Color.white, percentageComplete);
joystickHandle.color = Color.Lerp(new Color(1, 1, 1, 0), Color.white, percentageComplete);
if (PointerId >= 0 && PointerId < Input.touches.Length)
{
TouchDist = Input.touches[PointerId].position - PointerOld;
PointerOld = Input.touches[PointerId].position;
}
else
{
TouchDist = new Vector2(Input.mousePosition.x, Input.mousePosition.y) - PointerOld;
PointerOld = Input.mousePosition;
}
}
else
{
float timeSinceStarted = Time.time - timeStartedLerping;
float percentageComplete = timeSinceStarted / timeTakenDuringLerp;
joystick.GetComponent<Image>().color = Color.Lerp(Color.white, new Color(1, 1, 1, 0), percentageComplete);
joystickHandle.color = Color.Lerp(Color.white, new Color(1, 1, 1, 0), percentageComplete);
TouchDist = new Vector2();
}
}
public void OnPointerDown(PointerEventData eventData)
{
Pressed = true;
PointerId = eventData.pointerId;
PointerOld = eventData.position;
timeStartedLerping = Time.time;
joystick.RepostionJoystick(eventData);
}
public void OnPointerUp(PointerEventData eventData)
{
Pressed = false;
joystick.input = Vector2.zero;
joystick.handle.anchoredPosition = Vector2.zero;
}
public void OnDrag(PointerEventData eventData)
{
joystick.RepostionJoystick(eventData);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public float Horizontal { get { return (snapX) ? SnapFloat(input.x, AxisOptions.Horizontal) : input.x; } }
public float Vertical { get { return (snapY) ? SnapFloat(input.y, AxisOptions.Vertical) : input.y; } }
public Vector2 Direction { get { return new Vector2(Horizontal, Vertical); } }
public float HandleRange
{
get { return handleRange; }
set { handleRange = Mathf.Abs(value); }
}
public float DeadZone
{
get { return deadZone; }
set { deadZone = Mathf.Abs(value); }
}
public AxisOptions AxisOptions { get { return AxisOptions; } set { axisOptions = value; } }
public bool SnapX { get { return snapX; } set { snapX = value; } }
public bool SnapY { get { return snapY; } set { snapY = value; } }
[SerializeField] private float handleRange = 1;
[SerializeField] private float deadZone = 0;
[SerializeField] private AxisOptions axisOptions = AxisOptions.Both;
[SerializeField] private bool snapX = false;
[SerializeField] private bool snapY = false;
[SerializeField] protected RectTransform background = null;
[SerializeField] public RectTransform handle = null;
private RectTransform baseRect = null;
private Canvas canvas;
private Camera cam;
public Vector2 input = Vector2.zero;
protected virtual void Start()
{
HandleRange = handleRange;
DeadZone = deadZone;
baseRect = GetComponent<RectTransform>();
canvas = GetComponentInParent<Canvas>();
if (canvas == null)
Debug.LogError("The Joystick is not placed inside a canvas");
Vector2 center = new Vector2(0.5f, 0.5f);
background.pivot = center;
handle.anchorMin = center;
handle.anchorMax = center;
handle.pivot = center;
handle.anchoredPosition = Vector2.zero;
}
public virtual void OnPointerDown(PointerEventData eventData)
{
// OnDrag(eventData);
}
public void OnDrag(PointerEventData eventData)
{
}
public void RepostionJoystick(PointerEventData eventData)
{
cam = null;
if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
cam = canvas.worldCamera;
Vector2 position = RectTransformUtility.WorldToScreenPoint(cam, background.position);
Vector2 radius = background.sizeDelta / 2;
input = (eventData.position - position) / (radius * canvas.scaleFactor);
FormatInput();
HandleInput(input.magnitude, input.normalized, radius, cam);
handle.anchoredPosition = input * radius * handleRange;
}
protected virtual void HandleInput(float magnitude, Vector2 normalised, Vector2 radius, Camera cam)
{
if (magnitude > deadZone)
{
if (magnitude > 1)
input = normalised;
}
else
input = Vector2.zero;
}
private void FormatInput()
{
if (axisOptions == AxisOptions.Horizontal)
input = new Vector2(input.x, 0f);
else if (axisOptions == AxisOptions.Vertical)
input = new Vector2(0f, input.y);
}
private float SnapFloat(float value, AxisOptions snapAxis)
{
if (value == 0)
return value;
if (axisOptions == AxisOptions.Both)
{
float angle = Vector2.Angle(input, Vector2.up);
if (snapAxis == AxisOptions.Horizontal)
{
if (angle < 22.5f || angle > 157.5f)
return 0;
else
return (value > 0) ? 1 : -1;
}
else if (snapAxis == AxisOptions.Vertical)
{
if (angle > 67.5f && angle < 112.5f)
return 0;
else
return (value > 0) ? 1 : -1;
}
return value;
}
else
{
if (value > 0)
return 1;
if (value < 0)
return -1;
}
return 0;
}
public virtual void OnPointerUp(PointerEventData eventData)
{
//input = Vector2.zero;
//handle.anchoredPosition = Vector2.zero;
}
protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
{
Vector2 localPoint = Vector2.zero;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(baseRect, screenPosition, cam, out localPoint))
{
Vector2 pivotOffset = baseRect.pivot * baseRect.sizeDelta;
return localPoint - (background.anchorMax * baseRect.sizeDelta) + pivotOffset;
}
return Vector2.zero;
}
}
public enum AxisOptions { Both, Horizontal, Vertical }
these are the scripts interacting with each other to reposition the joysticks
Here is the original joystick without the modifications for the touchfield
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public float Horizontal { get { return (snapX) ? SnapFloat(input.x, AxisOptions.Horizontal) : input.x; } }
public float Vertical { get { return (snapY) ? SnapFloat(input.y, AxisOptions.Vertical) : input.y; } }
public Vector2 Direction { get { return new Vector2(Horizontal, Vertical); } }
public float HandleRange
{
get { return handleRange; }
set { handleRange = Mathf.Abs(value); }
}
public float DeadZone
{
get { return deadZone; }
set { deadZone = Mathf.Abs(value); }
}
public AxisOptions AxisOptions { get { return AxisOptions; } set { axisOptions = value; } }
public bool SnapX { get { return snapX; } set { snapX = value; } }
public bool SnapY { get { return snapY; } set { snapY = value; } }
[SerializeField] private float handleRange = 1;
[SerializeField] private float deadZone = 0;
[SerializeField] private AxisOptions axisOptions = AxisOptions.Both;
[SerializeField] private bool snapX = false;
[SerializeField] private bool snapY = false;
[SerializeField] protected RectTransform background = null;
[SerializeField] private RectTransform handle = null;
private RectTransform baseRect = null;
private Canvas canvas;
private Camera cam;
private Vector2 input = Vector2.zero;
protected virtual void Start()
{
HandleRange = handleRange;
DeadZone = deadZone;
baseRect = GetComponent<RectTransform>();
canvas = GetComponentInParent<Canvas>();
if (canvas == null)
Debug.LogError("The Joystick is not placed inside a canvas");
Vector2 center = new Vector2(0.5f, 0.5f);
background.pivot = center;
handle.anchorMin = center;
handle.anchorMax = center;
handle.pivot = center;
handle.anchoredPosition = Vector2.zero;
}
public virtual void OnPointerDown(PointerEventData eventData)
{
OnDrag(eventData);
}
public void OnDrag(PointerEventData eventData)
{
cam = null;
if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
cam = canvas.worldCamera;
Vector2 position = RectTransformUtility.WorldToScreenPoint(cam, background.position);
Vector2 radius = background.sizeDelta / 2;
input = (eventData.position - position) / (radius * canvas.scaleFactor);
FormatInput();
HandleInput(input.magnitude, input.normalized, radius, cam);
handle.anchoredPosition = input * radius * handleRange;
}
protected virtual void HandleInput(float magnitude, Vector2 normalised, Vector2 radius, Camera cam)
{
if (magnitude > deadZone)
{
if (magnitude > 1)
input = normalised;
}
else
input = Vector2.zero;
}
private void FormatInput()
{
if (axisOptions == AxisOptions.Horizontal)
input = new Vector2(input.x, 0f);
else if (axisOptions == AxisOptions.Vertical)
input = new Vector2(0f, input.y);
}
private float SnapFloat(float value, AxisOptions snapAxis)
{
if (value == 0)
return value;
if (axisOptions == AxisOptions.Both)
{
float angle = Vector2.Angle(input, Vector2.up);
if (snapAxis == AxisOptions.Horizontal)
{
if (angle < 22.5f || angle > 157.5f)
return 0;
else
return (value > 0) ? 1 : -1;
}
else if (snapAxis == AxisOptions.Vertical)
{
if (angle > 67.5f && angle < 112.5f)
return 0;
else
return (value > 0) ? 1 : -1;
}
return value;
}
else
{
if (value > 0)
return 1;
if (value < 0)
return -1;
}
return 0;
}
public virtual void OnPointerUp(PointerEventData eventData)
{
input = Vector2.zero;
handle.anchoredPosition = Vector2.zero;
}
protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
{
Vector2 localPoint = Vector2.zero;
if
(RectTransformUtility.ScreenPointToLocalPointInRectangle(baseRect, screenPosition, cam, out localPoint))
{
Vector2 pivotOffset = baseRect.pivot * baseRect.sizeDelta;
return localPoint - (background.anchorMax *
baseRect.sizeDelta) + pivotOffset;
}
return Vector2.zero;
}
}
public enum AxisOptions { Both, Horizontal, Vertical }
I gutted all the above from the project and added https://assetstore.unity.com/packages/tools/input-management/ultimate-touchpad-108921 to the project without altering anything. It is doing the exact same thing.
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.
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.
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;
}
}
}