Unity Inventory System 'error CS1001: Identifier expected' - c#

I am writing a simple script to create an inventory system, although I keep getting an 'Identifier Expected' error. I am trying to select the current item the script is attached to and add it to the inventory.
This is the error:
Assets\Scripts\ItemObject.cs(10,25): error CS1001: Identifier expected
The tutorial I am following: https://www.youtube.com/watch?v=SGz3sbZkfkg
Here is the Inventory System:
InventorySystem.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InventorySystem : MonoBehaviour
{
private Dictionary<InventoryItemData, InventoryItem> m_itemDictionary;
public List<InventoryItem> inventory {get; private set;}
private void Awake() {
inventory = new List<InventoryItem>();
m_itemDictionary = new Dictionary<InventoryItemData, InventoryItem>();
}
public void Add(InventoryItemData referenceData) {
if(m_itemDictionary.TryGetValue(referenceData, out InventoryItem value)) {
value.AddToStack();
} else {
InventoryItem newItem = new InventoryItem(referenceData);
inventory.Add(newItem);
m_itemDictionary.Add(referenceData, newItem);
}
}
public void Remove(InventoryItemData referenceData) {
if (m_itemDictionary.TryGetValue(referenceData, out InventoryItem value)) {
value.RemoveFromStack();
if(value.stackSize == 0) {
inventory.Remove(value);
m_itemDictionary.Remove(referenceData);
}
}
}
}
[Serializable]
public class InventoryItem {
public InventoryItemData data {get; private set;}
public int stackSize {get; private set;}
public InventoryItem(InventoryItemData source) {
data = source;
AddToStack();
}
public void AddToStack() {
stackSize++;
}
public void RemoveFromStack() {
stackSize--;
}
}
and here is the script that handles the item pickup:
ItemObject.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemObject : MonoBehaviour {
public InventoryItemData referenceItem;
public void OnHandlePickupItem() {
InventorySystem.this.Add(referenceItem);
Destroy(gameObject);
}
}
Any help would me much appreciated :)

You can not refer to InventorySystem with InventorySystem.this.Add(referenceItem) in ItemObject.
Try following:
Add the InventorySystem component to a GameObject in your Scene
Tag this GameObject with a tag named Inventory
With that you can find the InventorySystem by GameObject.findByTag (do this in the Awake method of ItemObject
Use this object for adding/removing stuff from/to the InventorySystem

Related

GetKeyDown sends multiple outputs

specifically it sends as many outputs as there are objects with the code in them that allows them to be interacted with, even if I press E when not looking at anything. I wanted to make an inventory system, but this causes all objects that have this code to be interacted with. I included all the scripts that im using for this system if that can help. I genuinely don't know what I did wrong
the interactor code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System;
public class Interactable : MonoBehaviour
{
public LayerMask interactableLayerMask;
//ITEM VARIABLE
public Item item;
//PICK UP RADIUS
public float radius = 4f;
public void Interact()
{
Debug.Log("Interacted with " + transform.name);
PickUp();
}
//PICK UP INTERACTION
void PickUp()
{
Debug.Log("Picking up " + item.name);
bool wasPickedUp = Inventory.instance.Add(item);
if (wasPickedUp)
Destroy(gameObject);
}
//INTERACTION
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
Debug.Log("Added item -----------------------------------------");
RaycastHit hit;
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, radius))
{
Interactable interactable = hit.collider.GetComponent<Interactable>();
if (interactable != null)
{
Interact();
}
} else
{
Debug.Log("Nothing");
}
}
}
}
the Inventory code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
#region Singleton
public static Inventory instance;
void Awake()
{
if (instance != null)
{
Debug.LogWarning("More than one instance of Inventory found!");
return;
}
instance = this;
}
#endregion
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;
public int space = 20;
public List<Item> items = new List<Item>();
public bool Add (Item item)
{
if (!item.isDefaultItem)
{
if (items.Count >= space)
{
Debug.Log("Note enough space in inventory");
return false;
}
else
{
items.Add(item);
if (onItemChangedCallback != null)
onItemChangedCallback.Invoke();
}
}
return true;
}
public void Remove(Item item)
{
items.Remove(item);
if (onItemChangedCallback != null)
onItemChangedCallback.Invoke();
}
}
Item code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
new public string name = "New Item";
public Sprite icon = null;
public bool isDefaultItem = false;
}
To my understanding, your code goes into the Input.GetKeyDown(KeyCode.E) for every object in the scene, but it does not add it to the inventory.
That is because you use the Update function in the Interactable class, which are your objects. Instead, try moving the exact same block of code into your Inventory class. Make sure you make your Interact method public, so you can call it.

How can I make an index system out of this system? Unity C#

I've done a system for tower building with help of brackeys tutorial. I want to select towers by index of scriptable object but i can't use arrays in TurretBP.
TurretBP is storing all the turret data
Buildmanager instantiates turres
And SelectTurret() method attached to buttons
Here is the code:
using UnityEngine;
using UnityEngine.UI;
public class Shop : MonoBehaviour
{
public TurretBP turret;
public TurretBP Jamsheed;
public TurretBP Farm;
public TurretBP Otbaphou;
public TurretBP Guard;
public int turretIdx;
BuildManager buildManager;
private void Start()
{
buildManager = BuildManager.instance;
}
public void SelectTurret()
{
buildManager.SelectTurretToBuild(turret);
}
public void SelectJamsheed()
{
buildManager.SelectTurretToBuild(Jamsheed);
}
public void SelectFarm()
{
buildManager.SelectTurretToBuild(Farm);
}
public void SelectOtbaphou()
{
buildManager.SelectTurretToBuild(Otbaphou);
}
public void SelectGuard()
{
buildManager.SelectTurretToBuild(Guard);
}
}
You can use arrays (idk why you've written that you can't):
[SerializeField] private TurretBP[] towers;
public enum Towers
{
TURRET = 0,
JAMSHEED = 1,
FARM = 2,
OTBAPHOU = 3,
GUARD = 4
}
public TurretBP GetTower(int index)
{
return towers[index];
}
Then you can call buildManager.SelectTurretToBuild(GetTower(Towers.Guard));
or buildManager.SelectTurretToBuild(GetTower(4));

UNET: Command function CmdSpawnPlayer called on server

I got an error from Unity while I was busy executing a command for the server. The error is:
Command function CmdSpawnPlayer called on server.
UnityEngine.Debug:LogError(Object)
NetworkHandler:CallCmdSpawnPlayer(Boolean)
NetworkHandler:OnEnable() (at Assets/Scripts/Managers/NetworkHandler.cs:69)
UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()
Here is the code I use:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
public class NetworkHandler : NetworkBehaviour
{
public Player NetworkPlayer
{
get;
private set;
}
public bool HasInternet
{
get
{
return Network.HavePublicAddress();
}
}
public bool IsConnectedToServer
{
get
{
return networkManager.isNetworkActive;
}
}
[SerializeField]
private NetworkManager networkManager;
[SerializeField]
private GameObject playerPrefab, spectatorPrefab;
public void StartClient()
{
networkManager.StartClient();
}
public void StartServer()
{
networkManager.StartServer();
}
[Command]
private void CmdSpawnPlayer(bool isSpectator)
{
SpawnPlayer(isSpectator);
}
private void SpawnPlayer(bool isSpectator)
{
if (isSpectator)
{
NetworkServer.SpawnWithClientAuthority(Instantiate(spectatorPrefab), connectionToClient);
}
else
{
NetworkServer.SpawnWithClientAuthority(Instantiate(playerPrefab), connectionToClient);
}
}
private void OnEnable()
{
if (IsConnectedToServer)
{
CmdSpawnPlayer(true);
Game.CameraHandler.InstantiateMode();
}
}
}
The Unity version is use is 5.3.4f1.
Okay, nevermind. It seems that I have called CmdSpawnPlayer(true); from the server instead of the LocalClient.

why can't call a function in A class but can call it in B class

I need to call updateGold() in ShowMoney class but failed.
If success,it should show money.gold in console, but don't show anything.
And golText.text don't update.
Even I change to Debug.Log("OK") in updateGold(),don't show anything in console.
But when I call updateGold() in Money class, it success. What the difference?
=========================================================
//Prop.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Prop : MonoBehaviour,IPointerClickHandler
{
public int goldPrice;
public int diamondPrice;
public int propID;
public GameObject goldError;
public GameObject diamondError;
public GameObject purchasePanel;
//check if purchased when back to this Level
void Awake()
{
if(Bag.propIsPurchased[propID]==true)
{
alreadySold();
}
}
//show purchase panel and add delegate
public void OnPointerClick (PointerEventData eventData)
{
purchasePanel.SetActive(true);
ConfirmPurchase.ensureOperation += this.purchase;
CancelPurchase.cancelOperation += this.cancel;
}
public void purchase()
{
if (goldPrice>0)
{
if(goldPrice > Money.gold)
{
goldError.SetActive(true);
}
else
{
Money.payGold(goldPrice);
ShowMoney.updateGold();//problem here
Bag.addProp(propID);
alreadySold();
}
}
//...
}
//...
//ShowMoney.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ShowMoney : MonoBehaviour
{
public GameObject goldText;
public GameObject diamondText;
public static Text golText;
public static Text diaText;
void Awake()
{
golText = goldText.GetComponent<Text>();
diaText = diamondText.GetComponent<Text>();
updateGold();
updateDiamond();
}
public static void updateGold()
{
Debug.Log(Money.gold);
golText.text = Money.gold.ToString();
}
public static void updateDiamond()
{
diaText.text = Money.diamond.ToString();
}
}
//Money.cs
using UnityEngine;
using System.Collections;
public class Money: MonoBehaviour
{
public static int gold = 100;
public static int diamond = 20;
public static Money instance;
void Awake()
{
instance = this;
}
public static void earnGold(int gol)
{
gold += gol;
}
public static void earnDiamond(int dia)
{
diamond += dia;
}
public static void payGold(int gol)
{
gold -= gol;
//ShowMoney.updateGold();//can work here
}
public static void payDiamond(int dia)
{
diamond -= dia;
}
}
Define your method Before Void and still Problem not solved then Make Protected Method that only accessible by its next method .
public static void updateGold()
{
Debug.Log(Money.gold);
golText.text = Money.gold.ToString();
}
public static void updateDiamond()
{
diaText.text = Money.diamond.ToString();
}
public void Awake()
{
golText = goldText.GetComponent<Text>();
diaText = diamondText.GetComponent<Text>();
updateGold();
updateDiamond();
}

Unity3D , Error GetItem(int 32)

i created 3 scripts for create an item , add item to list and show item.
When i'm trying get item to list , this error occurs.
NullReferenceException: Object reference not set to an instance of an object
charactersScript.GetItem (Int32 id)
the error is at line charactersScript.GetItem (Int32 id)
Here my scripts
itemdatabese for item class
using UnityEngine;
using System.Collections;
using System;
public class itemDataBase : ScriptableObject
{
public int itemID;
public int itemDamage;
public string itemName;
public itemDataBase(int _id, int _damage, string _name)
{
itemID = _id;
itemDamage = _damage;
itemName = _name;
}
}
technology script unlock for item and add to list
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class technologyScript : MonoBehaviour
{
public int countID = 0;
List<itemDataBase> item = new List<itemDataBase>();
public void StoneSpear()
{
countID += 1;
item.Add(new itemDataBase(countID, 7, "Stone Spear"));
}
}
and character script for show this item
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
public class charactersScript : MonoBehaviour
{
static public List<itemDataBase> _item;
static public itemDataBase GetItem(int id)
{
foreach (itemDataBase item in _item)
{
if (item.itemID == id)
{
return ScriptableObject.Instantiate(item) as itemDataBase;
}
}
return null;
}
public void rightWeapon()
{
weaponID += 1;
itemDataBase _item = GetItem(weaponID);
if (_item != null)
{
Debug.Log(_item.id);
}
}
}
is there any suggestion?
You are adding new itemDataBase() to one instance of List in technologyScript and then in charactersScript you are trying to loop through a different list (List<itemDataBase> _item) which is never instantiated and is null and throws the exception. The static list doesn't just automatically share the values of the other list just because you declared it with the static keyword.
Set your List<itemDataBase> item to public.
Try this:
foreach (itemDataBase item in GetComponent<technologyScript>().item)
{
if(item.itemID==id)
{
return ScriptableObject.Instantiate(item) as itemDataBase;
}
}
This presumes that technologyScript is on the same gameobject as this script, if not then you will need GameObject.Find(correctObj)...

Categories