- Home /
Can't find an argument that corresponds to a formal parameter for a function
I'm trying to reference another script's method through a singleton, and can't seem to find the right parameter for it.
if (Input.GetKeyDown(KeyCode.Alpha1))
{
if (currentlyEquipped != null)
{
Destroy(currentlyEquipped);
}
currentlyEquipped = Instantiate(slot1.GetComponent<InventorySlot>().item.Object, hand.position, hand.rotation, hand);
if(currentlyEquipped.GetComponent<Collider>())
{
currentlyEquipped.GetComponent<Collider>().enabled = false;
}
if(slot1.GetComponent<InventorySlot>().item.canEquip == true)
{
**EquipmentManager.instance.Equip();**
}
}
The line in bold is what is giving me errors, specifically under Equip();
Here is the method from the original script:
//Equip a new item
public void Equip (Equipment newItem)
{
//Find out what slot the item fits in
int slotIndex = (int)newItem.equipSlot;
Equipment oldItem = Unequip(slotIndex);
//An item has been equipped so we trigger the callback
if(onEquipmentChanged != null)
{
onEquipmentChanged.Invoke(newItem, oldItem);
}
//Insert the item into the slot
currentEquipment[slotIndex] = newItem;
SkinnedMeshRenderer newMesh = Instantiate<SkinnedMeshRenderer>(newItem.mesh);
newMesh.transform.parent = targetMesh.transform;
newMesh.bones = targetMesh.bones;
newMesh.rootBone = targetMesh.rootBone;
currentMeshes[slotIndex] = newMesh;
}
what are you asking?? The reason it is giving errors is because there is no method of that type that takes in Zero parameters. You must give it an object of type Equipment for it to be able to function.
So the structure I have observed is actually quite good. Have you created assets of Equipment? Also I would add GameObject Prefab to your Scriptable object to have a reference to your prefab. Then on the prefab you need to have a script that has a reference to the scriptable object (kind of like having each other in their contacts so they can talk to each other)
in your OnTriggerEnter you would then check if the collider had that script on it and if so then you could get the Scriptable object from it.
Answer by Stratosome · Jul 23, 2018 at 02:55 PM
Here's my interpretation of your code there. This Equip function inside of EquipmentManager is supposed to take in a piece of equipment ("newItem") and assign it to an inventory slot I guess. So, you are trying to call this function inside of your first code bit. If the Equip function expects an instance of the Equipment class as a parameter, then you need to give it an instance of Equipment when you call it. I'm not EXACTLY sure what you want, but it's looking like you put whatever Equipment you want equipped in as a parameter. You might want to make a new Equipment instance when something happens, and then equip that item using that function. Does that kind of help maybe?
Problem is, the Equipment class is a scriptable object. Is it possible to make an instance of a scriptable object? The second block of code you see, is from the Equipment$$anonymous$$anager class.
I've already got the inventory slots working, but now I am trying to get the hotbar working. Specifically, have the certain weapon/tool equip when the player presses the respective button. There's 6 slots, so if player presses 2, the second item in the hotbar gets equipped, or if it's a consumable/random item, it only shows up in the players hand.
Ah, gotchya, that's good to know. You can make instances of a scriptable object that show up in your project window, however, with my understanding at least, they are more of an editor thing? So you can make configuration type things with them for scripts and such? I guess how were you imagining this would work out? In game, you would find a piece of equipment, and it would then be placed in your inventory? How are you using scriptable object in this case? To make a bunch of predefined items and such?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAsset$$anonymous$$enu(fileName = "New Equipment", menuName = "Inventory/Equipment")]
public class Equipment : Item
{
public bool canEquip;
public EquipmentSlot equipSlot; //Slot to store equipment in
//public Skinned$$anonymous$$eshRenderer mesh; //What the player sees when it's equipped
public int armor$$anonymous$$odifier; // Increase/decrease in armor
public int damage$$anonymous$$odifier; //Increase/decrease in damage
public override void Use()
{
base.Use();
Equipment$$anonymous$$anager.instance.Equip(this);
RemoveFromInventory();
}
public void Equip()
{
Equipment$$anonymous$$anager.instance.Equip(this); // Equip it
RemoveFromInventory(); // Remove from inventory
}
}
public enum EquipmentSlot { Head, Body, Face, Back, Waist, Hands, Weapon, Leg, Foot }
Heres the Equipment class. And yes, it's a survival game so you could pick up items and equip/use them, and they show up in the equipment slots.
Answer by kalen_08 · Jul 23, 2018 at 11:20 PM
Okay so here you go... I have a few adjustments to make to your code. See below.
[CreateAssetMenu(fileName = "New Equipment", menuName = "Inventory/Equipment")]
public class Equipment : Item
{
// its always a good habit to make things '[SerializeField]"
// it makes the field visible and possible to set in the
// inspector while also keeping it protected.
// when things are public then they can be changed and when
// those things are saved assets then you won't be able to change them back.
// It would be like someone changing your phone #, you wouldn't like it and
// it wouldn't be good.
// instead it would be better to set your own phone # and if someone wants
// it then they can ask for it (hence why i created the properties down below.
// ATTRIBUTES
[SerializeField] bool canEquip;
[SerializeField] EquipmentSlot equipSlot; //Slot to store equipment in
public SkinnedMeshRenderer mesh; //What the player sees when it's equipped
[SerializeField] int armorModifier; // Increase/decrease in armor
[SerializeField] int damageModifier; //Increase/decrease in damage
// PROPERTIES
public bool CanEquip { get { return canEquip; } }
public int ArmorModifier { get { return armorModifier; } }
public int DamageModifier { get { return damageModifier; } }
public SkinnedMeshRenderer Mesh { get { return mesh; } }
// You'll notice i removed your functions here.
// that is because generally this is not for behaviour
// Behaviour scripts inherit from MonoBehaviour but this is
// data which is why it inherits from ScriptableObject.
// Scriptable objects are solely for the purpose of storing data
// which you've done a fine job of doing. but not behaviour.
// have a script maybe on the player which does everything as far as
// equiping everything, getting the items and showing them on the player.
// hope this helps!! remember to upvote and accept the best answer!! :)
}
When your player calls OnTriggerEnter () you would check if the object had one of the below scripts on it (you choose which is better! in fact it would be best to factor out GetEquitpment that way you can ask for the base class and the pickup can be either a specific pickup or random) and if so you would ask GetEquiptment and then you can do what you want with that.
public class ItemPickup : MonoBehaviour
{
[SerializeField] Equipment equiptment = null;
public Equipment GetEquiptment ()
{
return equiptment;
}
}
public class RandomItemPickup : MonoBehaviour
{
[SerializeField] List<Equipment> possibleEquiptment = new List<Equipment> ();
Equipment equiptment;
void Start ()
{
equiptment = possibleEquiptment[Random.Range(0, possibleEquiptment.Count)];
}
public Equipment GetEquiptment ()
{
return equiptment;
}
}
Your answer
Follow this Question
Related Questions
Button Listener void calling all prefab buttons in scene. 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
[C#] Equip weapon from Inventory 1 Answer