These two blocks of code I assume are involved with the following error:
Assets\Scripts\Weapons.cs(8,12): error CS7036: There is no argument given that corresponds to the required formal parameter 'name' of 'Item.Item(string, int)'
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Item : MonoBehaviour
{
private string name;
private int quantity;
public Item(string name, int quantity)
{
this.name = name;
this.quantity = quantity;
}
public string Name
{
get { return name; }
set { name = value; }
}
public int Quantity
{
get { return quantity; }
set { quantity = value; }
}
public virtual void UseItem()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapons : Item
{
public GameObject bullet;
public GameObject shotgunSpawn;
public GameObject shotgunSpawn2;
//public bool useGun;
public Inventory iw;
GUI_2D m;
public float Speed;
GameObject patroller;
GameObject guard;
public bool pellet;
public bool shotGun;
public bool barGun;
public PlayerController player;
// Start is called before the first frame update
void Start()
{
Speed = 5f;
player = GameObject.FindGameObjectWithTag("Player");
patroller = GameObject.FindGameObjectWithTag("Patroller");
guard = GameObject.FindGameObjectWithTag("Guard");
guard = GameObject.FindGameObjectWithTag("Shotgun");
pellet = false;
shotGun = false;
barGun = false;
}
void DestroyEnemy()
{
if (patroller)
{
patroller.SetActive(false);
}
if (guard)
{
patroller.SetActive(false);
}
}
private void OnTriggerEnter(Collider other)
{
if (iw.invItems.Count < 12)
{
if (other.gameObject.CompareTag("Player"))
{
pellet = true;
}
}
}
public override void UseItem()
{
if (pellet)
{
player.pellet = true;
player.shotGun = false;
player.barGun = false;
}
if (shotGun)
{
player.pellet = false;
player.shotGun = true;
player.barGun = false;
}
if (barGun)
{
player.pellet = false;
player.shotGun = false;
player.barGun = true;
}
base.UseItem();
}
}
I am not trying to change the item class since doing so will affect another class that depends on the item classes constructor. Unless there is another way to resolve the error by changing the item class. The error given is also affecting another class in the same way. I am hoping to solve the issue in both the weapon class and the other class from an answer here. Thank you in advance.
You shouldn't add constructors to MonoBehaviours, as the Unity Engine is responsible for instantiating them and will never pass your constructors arguments (you shouldn't be creating instances of MonoBehaviours, either).
Just remove your Item constructor and assign the values manually whenever needed. Other construction code should be done in Awake() or Start().
Related
I want to create public Scene[] levels; and manually assign my levels to the array, then loop through it and generate level selection buttons, but it won't show up in the inspector.
Is there any workaround?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class True : MonoBehaviour
{
// Start is called before the first frame update
public static int money;
[SerializeField]
public SceneManager[] scenes;
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void nextscencefirst()
{
SceneManager.LoadScene("Level2");
money++;
}
}
SceneManager is a built-in static class to control scenes during runtime. We can go to any scene by calling LoadScene method from that class. Also SceneManager cannot be seen in Inspector since it cannot be serialized class.
A reminder: Your scenes should be listed on build settings for these to work.
There are three ways to do what you want to do:
Method 1. Create a string list that holds names of scenes
public List<string> sceneNameList = new List<string>;
Method 2. Create a list of indices of scenes that added in build settings.
public List<int> sceneBuildIndexList = new List<int>
If the names of scenes are long or somehow difficult or you want to use sceneBuildIndex value it would be good to create a class and reach scenes from it
[System.Serializable]
public class SceneData
{
public int sceneBuildIndex;
public string sceneKey;
//public void LoadScene() //Maybe
}
public List<SceneData> sceneDataList = new List<SceneData>();
public SceneData GetSceneData(string key)
{
for (int i = 0; i < sceneDataList.Count; i++)
{
if (sceneDataList[i].sceneKey == key)
{
return sceneDataList[i];
}
}
return null;
}
Method 3: In Unity most classes are created from UnityEngine.Object, so it may let you assign scene from the Inspector.
[System.Serializable]
public class SceneData
{
public UnityEngine.Object scene;
public string key;
public void LoadScene()
{
if (scene == null)
{
Debug.LogError("Scene is not assigned");
return;
}
string pathToScene = AssetDatabase.GetAssetPath(scene);
SceneManager.LoadScene(pathToScene); //If the scene is not set in BuildSettings it will throw an error.
}
}
public List<SceneData> sceneDataList = new List<SceneData>();
public SceneData GetSceneData(string key)
{
for (int i = 0; i < sceneDataList.Count; i++)
{
if (sceneDataList[i].key == key)
{
return sceneDataList[i];
}
}
return null;
}
private void Awake()
{
SceneData data = GetSceneData("Level1");
if (data != null)
{
data.LoadScene();
}
}
I am super new to C#, so apologies if this is a simple question or has already been answered. I've been looking at other SO questions, trying the exact methods they use, and am still having no luck.
In Unity, I have an Inventory Object class that I can use to create Inventories in my game:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Inventory", menuName = "Inventory System/Inventory")]
public class InventoryObject : ScriptableObject
{
public List<InventorySlot> Container = new List<InventorySlot>();
public void AddItem(ItemObject newItem, int itemAmount)
{
bool inventoryHasItem = false;
for (int i = 0; i < Container.Count; i++)
{
if (CurrentSlotHasItem(Container[i], newItem)) {
if (Container.FindAll((InventorySlot currentSlot) => CurrentSlotHasItem(currentSlot, newItem)).Count < newItem.maxStackSize)
{
Container[i].AddAmount(itemAmount);
inventoryHasItem = true;
break;
}
}
}
if (!inventoryHasItem)
{
Container.Add(new InventorySlot(newItem, itemAmount));
}
}
private bool CurrentSlotHasItem(InventorySlot currentSlot, ItemObject item)
{
return currentSlot.item == item;
}
}
[System.Serializable]
public class InventorySlot
{
public ItemObject item;
public int amount;
public InventorySlot(ItemObject _item, int _amount)
{
item = _item;
amount = _amount;
}
public void AddAmount(int value)
{
amount += value;
}
}
This works great, except for this line:
Container.FindAll((InventorySlot currentSlot) => CurrentSlotHasItem(currentSlot, newItem)).Count < newItem.maxStackSize
For some reason, no matter what I use for the findAll() predicate, I always get the same amount in my inspector - 1. Which means that .Count never goes above 1, and I can go way above my ItemObject.maxStackSize.
This is an example ItemObject class I have:
using UnityEngine;
[CreateAssetMenu(fileName = "New Food Object", menuName = "Inventory System/Items/Food")]
public class FoodObject : ItemObject
{
public int healthAmount;
private void Awake() {
type = ItemType.Food;
maxStackSize = 25;
}
}
This is also my Player script that adds the items to the inventory. It just adds them based off of OnTriggerEnter.
public class Player : MonoBehaviour
{
public InventoryObject inventory;
private void OnTriggerEnter(Collider other)
{
var item = other.GetComponent<Item>();
if (item)
{
inventory.AddItem(item.item, 1);
Destroy(other.gameObject);
}
}
}
Here's some screenshots of my Unity console/inspector, with these two lines added to my InventoryObject class. You can see that .Count never going above 1.
if (CurrentSlotHasItem(Container[i], newItem)) {
Debug.Log(Container.FindAll((InventorySlot currentSlot) => CurrentSlotHasItem(currentSlot, newItem)).Count);
Debug.Log(Container[i].amount);
// rest of class
I don't know what I was thinking here. All I needed to do to get maxStackSize to work was changing the logic inside of AddItem:
for (int i = 0; i < Container.Count; i++)
{
if (Container[i].item.id == newItem.id) {
if (Container[i].amount < newItem.maxStackSize)
{
Container[i].AddAmount(itemAmount);
inventoryHasItem = true;
break;
}
}
}
It just compares Container[i].amount to newItem.maxStackSize. If it's under, it will stack the item. Otherwise, it creates a new item in the inventory.
quick introduction to my project. I am trying to make a game in unity game engine and I am working on its shop system. Everything about the shop system is complete but one problem is still there. I need to save the State of button that is (MyButton) in my game scene and change it with (BuyButton) or (EquipButton) the saving part works but setting the button doesn't, I am using enum and switch statements for that part. These are the scripts of those two things.
script with the enum:
using UnityEngine;
using System.IO;
public class SaveEverything : MonoBehaviour
{
// What script to save
public LoadEveryThing MyButton;
public void Save()
{
// What data to save
string saveData = MyButton.state.ToString();
// Where the data is stored
string path = Application.persistentDataPath + "\\buttonstate.save";
// Writes data to file
if (File.Exists(path))
{
File.WriteAllText(path, saveData/*, saveData1, saveData2, saveData3, 5*/);
}
else
{
File.Create(path).Close();
File.WriteAllText(path, saveData/*, saveData1, saveData2, saveData3, 5*/);
}
}
}
public enum ButtonState
{
Buy,
Equip
}
At the last part of script the enum is declared, with Buy and Equip inside it and rest of the script is about saving MyButton in a string.
Script with the switch statement:
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System;
using TMPro;
public class LoadEveryThing : MonoBehaviour
{
// Types of buttons
public GameObject BuyButton;
/* public GameObject BuyButton1;
public GameObject BuyButton2;
public GameObject BuyButton3;*/
public GameObject EquipButton;
/*public GameObject EquipButton1;
public GameObject EquipButton2;
public GameObject EquipButton3;*/
public ButtonState state;
void Start()
{
// What file to read save data from
string path = Application.persistentDataPath + "\\buttonstate.save";
// Get data and set state to that data
if (File.Exists(path))
{
string data = File.ReadAllText(path);
if (Enum.TryParse(data, out ButtonState State))
state = State;
}
// Copy button properties onto this button
// depending on the state
switch (state)
{
case ButtonState.Buy:
SetButton(BuyButton);
break;
case ButtonState.Equip:
SetButton(EquipButton);
break;
}
if(shop.isSold == true)
{
state = ButtonState.Equip;
Debug.Log("working");
}
else if(shop.isSold == false)
{
state = ButtonState.Buy;
Debug.Log(" buy working");
}
}
void Update()
{
}
void SetButton(GameObject button)
{
// Set on-click method of button
Button myButton = GetComponent<Button>();
Button targetButton = button.GetComponent<Button>();
myButton.onClick = targetButton.onClick;
// Set text of button
TMPro.TextMeshProUGUI myText = GetComponentInChildren<TMPro.TextMeshProUGUI>();
TMPro.TextMeshProUGUI targetText = button.GetComponentInChildren<TMPro.TextMeshProUGUI>();
myText.text = targetText.text;
}
/*public static void SetEquipButton()
{
}
public static void SetBuyButton()
{
}*/
}
In the script the switch statement works like this if the enum ButtonState is ButtonState.Buy then it actives buy button else it active and sets Equip button. But the problem is I don't know how to change the ButtonScript State through script. So the switch statement doesn't have anything to change and save BuyButton to EquipButton. I had already tried this /*I made this variable of type ButtonState*/ public ButtonState state and then I did this to change the enum State state = ButtonState.Equip; but it is not changing the State of the enum. I can see that in the inspector and there are not errors as well. So what should I do?
This is the script where I am calling to change the enum state:
the script is too long so this is the method where I am calling it and I also as told I already made a variable of type public ButtonState state;
public class shop : MonoBehaviour
{
public TMPro.TextMeshProUGUI scoreText;
public GameObject Item1;
public GameObject Item2;
public GameObject Item3;
public GameObject Item4;
public TMPro.TextMeshProUGUI notenough;
public TMPro.TextMeshProUGUI notenough1;
public TMPro.TextMeshProUGUI notenough2;
public TMPro.TextMeshProUGUI notenough3;
public GameObject buyButton;
public GameObject buyButton1;
public GameObject buyButton2;
public GameObject buyButton3;
public GameObject equipButton;
public GameObject equipButton1;
public GameObject equipButton2;
public GameObject equipButton3;
public float sec = 14f;
public static bool isSold = false;
public static bool isSold1 = false;
public static bool isSold2 = false;
public static bool isSold3 = false;
public ButtonState state;
public ButtonState1 state1;
public ButtonState2 state2;
public ButtonState3 state3;
private Dictionary<GameObject, float> ItemPrices;
void Start ()
{
scoreText.text = "Score : " + ((int)PlayerPrefs.GetFloat ("Highscore")).ToString();
ItemPrices = new Dictionary<GameObject, float>()
{
{ Item1, 50f },
{ Item2, 80f },
{Item3, 3500f},
{ Item4, 5000f },
};
notenough.enabled = false;
notenough1.enabled = false;
notenough2.enabled = false;
notenough3.enabled = false;
}
public void PurchaseItem(GameObject Item)
{
foreach(KeyValuePair<GameObject, float> item in ItemPrices)
{
if (item.Key == Item)
{
float price = item.Value;
float val = PlayerPrefs.GetFloat ("Highscore");
if(val >= price)
{
val -= item.Value;
PlayerPrefs.SetFloat("Highscore", val);
scoreText.text = "Score : " + ((int)PlayerPrefs.GetFloat ("Highscore")).ToString();
buyButton.SetActive(false);
equipButton.SetActive(true);
isSold = true;
state = ButtonState.Equip;
// Take away the cost of the item from the player's currency
//PlayerPrefs.GetFloat ("Highscore") -= item.Value;
}
else
{
Debug.Log("not enough money");
notenough.enabled = true;
notenough1.enabled = true;
notenough2.enabled = true;
notenough3.enabled = true;
Invoke("noen", 2);
state = ButtonState.Buy;
}
}
}
}
public void noen()
{
notenough.enabled = false;
notenough1.enabled = false;
notenough2.enabled = false;
notenough3.enabled = false;
}
}
If any thing is unclear let me know.
Thanks,
Here is the code I am using:
public enum TargetingOptions
{
NoTarget,
AllCreatures,
EnemyCreatures,
YourCreatures,
AllCharacters,
EnemyCharacters,
YourCharacters
}
public enum Faction
{
Fog,
Imperial,
Monster,
Pirate
}
public class CardAsset : ScriptableObject
{
public CharacterAsset characterAsset;
[TextArea(2, 3)]
public string Description;
public Sprite CardImage;
public int ManaCost;
[Header("Faction")]
public Faction faction;
[Header("Creature Info")]
public int MaxHealth;
public int Attack;
public int AttacksForOneTurn = 1;
public bool Charge;
public string CreatureScriptName;
public int specialCreatureAmount;
[Header("SpellInfo")]
public string SpellScriptName;
public int specialSpellAmount;
public TargetingOptions Targets;
}
what I am trying to do is create a different "hand" of cards depending on faction. to do this I have created a separate "hand" script for each of the factions, but I want to create a "handmultiple" script that will choose which "hand faction" script to head to.
So if in unity "pirate" is chosen, then all that will appear would be the associated scripts (ignoring fog, imperial and pirate scripts)
Does that make sense?
thank you!
enter code here using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
public class HandVisualImperial : MonoBehaviour
{
public AreaPosition owner;
public bool TakeCardsOpenly = true;
public SameDistanceChildren slots;
[Header("Transform References")]
public Transform DrawPreviewSpot;
public Transform DeckTransform;
public Transform OtherCardDrawSourceTransform;
public Transform PlayPreviewSpot;
private List<GameObject> CardsInHand = new List<GameObject>();
public void AddCard(GameObject card)
{
CardsInHand.Insert(0, card);
card.transform.SetParent(slots.transform);
PlaceCardsOnNewSlots();
UpdatePlacementOfSlots();
}
public void RemoveCard(GameObject card)
{
CardsInHand.Remove(card);
PlaceCardsOnNewSlots();
UpdatePlacementOfSlots();
}
So I think I have it figured out:
Have a whole bunch more work to do before testing it unfortunately.. but I believe I have it done now... Thank you all for the help!!!
public class HandVisualMultiple : MonoBehaviour
{
Faction factiontype;
public HandVisualFog fog;
public HandVisualImperial imperial;
public HandVisualMonster monster;
public HandVisualPirate pirate;
void Start()
{
fog = GetComponent<HandVisualFog>();
imperial = GetComponent<HandVisualImperial>();
monster = GetComponent<HandVisualMonster>();
pirate = GetComponent<HandVisualPirate>();
if (factiontype == Faction.Fog)
{
fog.enabled = true;
imperial.enabled = false;
monster.enabled = false;
pirate.enabled = false;
}
else if (factiontype == Faction.Imperial)
{
fog.enabled = false;
imperial.enabled = true;
monster.enabled = false;
pirate.enabled = false;
}
else if (factiontype == Faction.Monster)
{
fog.enabled = false;
imperial.enabled = false;
monster.enabled = true;
pirate.enabled = false;
}
else if (factiontype == Faction.Pirate)
{
fog.enabled = false;
imperial.enabled = false;
monster.enabled = false;
pirate.enabled = true;
}
}
}
It's not the answer for your question, but an experienced game developer advice.
Try to use Polimorfism. A single main class. "class Creature" and then a lot of child classes class ImperialCreature:Creature, class PirateCreature:Creature and then set the parameters to each of them.
And later you can set another sub classes. for instance: class JackSparrow:PirateCreature ... and on...
The enum is similar to an array, so if you do (int)Faction.Fog it will return 0 since it's the first item. You could have an array or list with your scripts in the same order as your enum and call them by casting the enum to an int
Please help me fix the error.
The message is:
"Assets/Scripts/GameManager.cs(6,21): error CS0118: GameManager.character' is afield' but a `type' was expected"
The error is on (6, 21). Thanks.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameManager : MonoBehaviour {
public List<character> character = new List<character>(); <-- (ERROR CS0118)
bool ShowCharWheel;
public int SelectedCharacter;
public int xcount;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.C)){
{
ShowCharWheel = true;
}
{
ShowCharWheel = false;
}
//Camera.main.GetComponent<SmoothFollow>().target = characters[SelectedCharacter].
if (ShowCharWheel)
{
GUILayout.BeginArea(new Rect(Screen.width - 64, Screen.height - 192,64,192));
{
if(GUILayout.Button(c.icon,GUILayout.Width(64),GUILayout.Height(64)))
foreach (character c in Characters)
{
SelectedCharacter = character.IndexOf(c);
}
}
}
GUILayout.EndArea();
}
}
}
[System.Serializable]
public class Character
{
public string name;
public Texture2D icon;
public GameObject prefab;
public GameObject instance;
public Transform HomeSpawn;
}
Needed more details other than code, so ignore this.
Do you perhaps just need to capitalize? C# is case sensitive.
public List<Character> characterList = new List<Character>();
I also renamed your variable for clarity.