How to access different Ore from my mining script

Okay! So in the last few days my mining script has gotten quite far and it now resembles quite a simple but effective mining system. You are able to collect ore, gain EXP and level up. This mining option is only available when you enter the trigger zone surrounding the ore.

My problem is my mining script only handles one kind of ore right now which is bronze ore. The last thing i want my script to be able to do before i’m happy is to be able to allow it to mine different ores. And as well as that, gain different EXP for different ores and also not be able to mine various ores until your current level is high enough.

Below is my current code (mining system). If anyone could tell me the steps forward i’d have to take towards adding these extra ores to my system then i’d be really grateful :')!

(Note, this script is attached to my first person character).

using UnityEngine;
using System.Collections;

public class MiningSkill : MonoBehaviour
{
   
    public int miningXP;
    public bool toggleMine = false;
    public bool guiOn = false;
    public int curMiningLevel;
    public bool mining;
    public float mineTime;
    public float mineDelay = 3f;
    public Animation mineSwing;
    public int bronzeOre;
    public int multiplier;
    public int baseXP;
    public int remainingXP;
    public GUISkin parchment;
   
   
    void OnGUI()
    {
       
        if (toggleMine)
        {
           
            if (Input.GetMouseButtonDown(0))
            {
                mining = true;
                toggleMine = false;
                mineTime = 0f;
               
            }
            GUI.Button(new Rect(5, 160, 100, 50), "Left Click \n To Mine");
           
           
           
           
        }
       
       
       
        if (guiOn)
        {
            GUI.skin = parchment;
            GUI.Box(new Rect(5, 50, 100, 50), "Mining XP" + ":" + " " + miningXP + "\n Current Mining\n Level" + ":" + " " + curMiningLevel);
            GUI.Box(new Rect(5, 105, 100, 50), "Bronze Ore" + ":" + " " + bronzeOre);
            GUI.Box(new Rect(5, 225, 100, 50), "Remaining XP" + ":" + "\n " + remainingXP);
           
           
           
        }
       
    }
   
    void OnTriggerEnter(Collider playerEnterOre)
    {
        toggleMine = true; //If the player is within range of the ore, a button will appear that allows the player to mine
    }
   
   
    void OnTriggerExit(Collider playerExitOre)
    {
        toggleMine = false; //if the player is not within range of the ore. The button will not appear.
        mining = false; //if the player exits the trigger area whilst mining is in progress, cancel mine function.
    }
   
   
   
   
   
    void Update()
    {
       
        if (Input.GetKeyDown(KeyCode.LeftShift)) guiOn = !guiOn;
       
        if (mining)
        {
           
            mineTime += Time.deltaTime;
           
            if (mineTime >= mineDelay)
            {
               
                mining = false;
                toggleMine = true;
               
                if (Random.value > 0.45)
                {
                    MineOre((int) 5, (string) "bronze");
                }
                else
                {
                    Debug.Log("You Missed The Rock");
                   
                   
                }
            }
        }
    }
   
    void MineOre(int xpInc, string ore)
    {
        miningXP += xpInc;
        switch (ore) //Swith is like if statement but better if comparing one varibale like ore to a lot of constants like iron bronze...
        {
        case "bronze":
            bronzeOre++;
            print("You got bronze ore!");
            break;
        case "iron":
            //ironOre++;       or any other ore variable you want
            print("You got iron ore!");
            break;
        default :  //Default is called when none of cases are true
            print("YOU GET NOTHING!");
            break;
           
        }
       
       
        if (miningXP >= curMiningLevel * multiplier + baseXP)
        {
            curMiningLevel++;
            Debug.Log("Congratulations You've Reached Level" + " " + curMiningLevel); //On level up print new level
            miningXP = 0; // hard reset to 0
           
        }
        remainingXP = curMiningLevel * multiplier + baseXP - miningXP;
       
       
    }

}

Can you send picture of trigger in editor. Where you put collider, what are options of collider. Thanks

In the trigger area you could have a script with a static variable, then:

void OnTirggerEnter(Collider playerEnterOre) {
   public int oretype = Collider.gameObject.GetComponent<InsertYourScriptNameHere>.oretype;
}

then the xp and can't mine thingy:

switch (oretype) {
   case 1: // bronze
      miningXp += 5;
      bronze++;
      break;
   case 2: //iron or something
      if (miningLevel > 2) {
         iron++;
         miningXP += 5;
      } else {
         Debug.Log("you can't mine that");
      } etc...
}
1 Like

Exactly what i tought but needed picture to show complete example

Here you go :slight_smile:

This Script goes to your Ore object and change give xp and give ore in inspector (5 give xp to give player 5 xp and bronze give ore to give player bronze ore

using UnityEngine;
using System.Collections;

public class Ore : MonoBehaviour
{

    public bool toggleMine = false;
    public bool guiOn = false;
    public bool mining;
    public float mineTime;
    public float mineDelay = 3f;
    public Animation mineSwing;
    public GUISkin parchment;
    public int giveXP;
    public string giveOre
  
  
    void OnGUI()
    {
      
        if (toggleMine)
        {
          
            if (Input.GetMouseButtonDown(0))
            {
                mining = true;
                toggleMine = false;
                mineTime = 0f;
              
            }
            GUI.Button(new Rect(5, 160, 100, 50), "Left Click \n To Mine");
          
          
          
          
        }
      
      
      
        if (guiOn)
        {
            GUI.skin = parchment;
            GUI.Box(new Rect(5, 50, 100, 50), "Mining XP" + ":" + " " + Player.miningXP + "\n Current Mining\n Level" + ":" + " " + Player.curMiningLevel);
            GUI.Box(new Rect(5, 105, 100, 50), "Bronze Ore" + ":" + " " + Player.bronzeOre);
            GUI.Box(new Rect(5, 225, 100, 50), "Remaining XP" + ":" + "\n " + Player.remainingXP);
          
          
          
        }
      
    }
  
    void OnTriggerEnter(Collider playerEnterOre)
    {
        toggleMine = true; //If the player is within range of the ore, a button will appear that allows the player to mine
    }
  
  
    void OnTriggerExit(Collider playerExitOre)
    {
        toggleMine = false; //if the player is not within range of the ore. The button will not appear.
        mining = false; //if the player exits the trigger area whilst mining is in progress, cancel mine function.
    }
  
  
  
  
  
    void Update()
    {
      
        if (Input.GetKeyDown(KeyCode.LeftShift)) guiOn = !guiOn;
      
        if (mining)
        {
          
            mineTime += Time.deltaTime;
          
            if (mineTime >= mineDelay)
            {
              
                mining = false;
                toggleMine = true;
              
                if (Random.value > 0.45)
                {
                    Player.MineOre(giveXP, giveOre);
                }
                else
                {
                    Debug.Log("You Missed The Rock");
                  
                  
                }
            }
        }
    }
  
}

This goes to player script

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
    public static int multiplier = 2;
    public static int baseXP = 20;
    public static int miningXP = 0;
    public static int curMiningLevel = 1;
    public static int remainingXP = 0;
    public static int bronzeOre = 0;
    public static int ironOre = 0;

    public static void MineOre(int xpInc, string ore)
    {
        miningXP += xpInc;
        switch (ore) //Swith is like if statement but better if comparing one varibale like ore to a lot of constants like iron bronze...
        {
        case "bronze":
            bronzeOre++;
            print("You got bronze ore!");
            break;
        case "iron":
            //ironOre++;       or any other ore variable you want
            print("You got iron ore!");
            break;
        default :  //Default is called when none of cases are true
            print("YOU GET NOTHING!");
            break;
          
        }
      
      
        if (ore.miningXP >= curMiningLevel * multiplier + baseXP)
        {
            curMiningLevel++;
            Debug.Log("Congratulations You've Reached Level" + " " + curMiningLevel); //On level up print new level
            miningXP = 0; // hard reset to 0
          
        }
        remainingXP = curMiningLevel * multiplier + baseXP - miningXP;
      
      
    }
  
}

At start is public class Player : Monobehaviour

and that means script needs to be named player. same goes for first script.
this should work

EDIT: try to edit thoese collider because might not work now. i can fix later when i come home

1 Like

Seem to be getting this error

Assets/Sam/Player Skills/Mining/Player.cs(34,25): error CS1061: Type string' does not contain a definition for miningXP’ and no extension method miningXP' of type string’ could be found (are you missing a using directive or an assembly reference?)

Any ideas :)?

Look at the function’s end, ore is defined as a string, not as a type of an ore, instead you could do this

switch (ore) {
   case "bronze":
      bronzeOre++;
      print("You got bronze ore");
      currentMiningXp += replacethiswiththeminingxpofbronze;
      break;
} ...
...
...
if (currentMiningXp >= curMiningLevel * multiplier +baseXp) {
   curMiningLevel++;
   currentMiningXp -= curMiningLevel * multiplier +baseXp;
}

for that error remove ore. it was my mistake

Also can you take picture of place where your mining skill script was assigned (Player.cs) In this case

i need it to fix collieders

You mean this :)?

Ok here is complete working scripts (maybe some little mistakes)
Put this code to each ore:

using UnityEngine;
using System.Collections;
public class Ore : MonoBehaviour
{
    public int xpAmount;
    public string oreType;

    public int XP()
    {
        return xpAmount;
    }

    public string Type()
    {
        return oreType;
    }
}

and this code goes to player (you are not using animation refference anywhere but ok)

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
    //Player RPG elements
    public int xp;
    public int miningLevel = 1;
    public int multiplier = 2;
    public int baseXp = 20;

    //Stores amount of ore
    public int bronzeOre = 0;
    public int ironOre = 0;

    int remainingXP = 0;

    //Stores refference to ore
    int xpIncrease;
    string oreType;

    //your gui and other things
    GUISkin parchment;
    bool toggleMine = false;
    bool guiOn = false;
    bool mining;
    float mineTime;
    public float mineDelay = 3f;
    public Animation mineSwing;

    public void MineOre(int xpInc, string ore)
    {
        xp += xpInc;
        switch (ore)
        {
            case "bronze":
                bronzeOre++;
                print("You got bronze ore!");
                break;
            case "iron":
                ironOre++;
                print("You got iron ore!");
                break;
            default:  //Default is called when none of cases are true
                print("YOU GET NOTHING!");
                break;

        }


        if (xp >= miningLevel * multiplier + baseXp)//this is basic formula which you can later edit to suit how fast player should advance
        {
            miningLevel++;
            print("Congratulations You've Reached Level" + miningLevel); //On level up print new level
            xp = 0; // hard reset to 0
        }
        remainingXP = miningLevel * multiplier + baseXp - xp;
    }

    void OnGUI()
    {

        if (toggleMine)
        {

            if (Input.GetMouseButtonDown(0))
            {
                mining = true;
                toggleMine = false;
                mineTime = 0f;

            }
            GUI.Button(new Rect(5, 160, 100, 50), "Left Click \n To Mine");




        }



        if (guiOn)
        {
            GUI.skin = parchment;
            GUI.Box(new Rect(5, 50, 100, 50), "Mining XP: " + xp + "\n Current Mining\n Level: " + miningLevel);
            GUI.Box(new Rect(5, 105, 100, 50), "Bronze Ore: " + bronzeOre);
            GUI.Box(new Rect(5, 225, 100, 50), "Remaining XP:\n" + remainingXP);



        }

    }

    void OnTriggerEnter(Collider other)
    {
        toggleMine = true; //If the player is within range of the ore, a button will appear that allows the player to mine
        xpIncrease = other.GetComponent<Ore>().XP();
        oreType = other.GetComponent<Ore>().Type();
    }


    void OnTriggerExit(Collider other)
    {
        toggleMine = false; //if the player is not within range of the ore. The button will not appear.
        mining = false; //if the player exits the trigger area whilst mining is in progress, cancel mine function.
    }

    void Update()
    {

        if (Input.GetKeyDown(KeyCode.LeftShift)) guiOn = !guiOn;

        if (mining)
        {

            mineTime += Time.deltaTime;

            if (mineTime >= mineDelay)
            {

                mining = false;
                toggleMine = true;

                if (Random.value > 0.45)
                {
                    MineOre(xpIncrease, oreType);
                }
                else
                {
                    Debug.Log("You Missed The Rock");
                }
            }
        }
    }
}

just edit variables in ore.
for instance if you want ore to give bronze and 5 xp
you change xpAmount to 5 and oreType to bronze and when you mine it will give you bronze ore and 5 xp

Before i change anything may i ask how exactly this will change things? Just with the previous script they weren’t any errors and the behavior i got from it is actually how i wanted the system to behave anyways. I can set ores to different types and control how much xp i get from each, animations gui and collisions are also fine. As well as that i also managed to set it up so that i can’t mine a certain ore unless i’m a certain level. So would i not be able to just stick with this script if it already works fine :')?

This is pretty much the same.
But now you can edit each ore to give what you want, just that it is dynamic and can be expanded easier.
as far as i see now you dont have system for required level but that can be add easily also

Ah perfect i have it working! Only error i found was having to change the GUISkin to public so that i could set the skin in the inspector! Also if you’re wondering how i set the level required function up here is the code :slight_smile:

case "iron":
            if(miningLevel >= 5)
            {
                ironOre++;    
                print("You got Iron Ore!");
            }
          
            else
            {
                Debug.Log("You Need To Be Level 5 To Mine Iron ore!");
                xp = xp - 15;
            }

the xp = xp -15 is there to make sure no xp is gained or lost when attempting to mine to rock (xp gained from iron ore is 15). I guess the only step left now is to try and replace the Debug.log statements with some kind of GUI :')

i would change that

using UnityEngine;
using System.Collections;
public class Ore : MonoBehaviour
{
    public int xpAmount;
    public int reqLevel;
    public string oreType;
    public int XP()
    {
        return xpAmount;
    }
    public string Type()
    {
        return oreType;
    }

   public int ReqLevel()
   {
      return reqLevel;
   }
}

change this part of player code

void OnTriggerEnter(Collider other)
    {
        toggleMine = true; //If the player is within range of the ore, a button will appear that allows the player to mine
        xpIncrease = other.GetComponent<Ore>().XP();
        oreType = other.GetComponent<Ore>().Type();
        reqLevel = other.GetComponent<Ore>().ReqLevel();
    }

and change this in update function

if (mining && reqLevel >= miningLevel)
        {
            mineTime += Time.deltaTime;
            if (mineTime >= mineDelay)
            {
                mining = false;
                toggleMine = true;
                if (Random.value > 0.45)
                {
                    MineOre(xpIncrease, oreType);
                }
                else
                {
                    Debug.Log("You Missed The Rock");
                }
            }
        }

also at initialization of player script near other initialization variables put this

int reqLevel;

your code works but this way you can set at ore how big level is required to mine and no need to subtract xp

also if you increase variable instead of xp = xp + 15 you can use xp += 15

I’ve done everything you’ve said and i’m able to set a level for my ore but when i hit it’s displaying i need to be level 5 to mine but still giving my player Exp for it. Did i miss something??

@SaamBell I would need to see code as my code here is good, It wont give ore or xp if its not big enough level

Here you are :slight_smile:

:sweat_smile:
its miningLevel >= reqLevel
hahahahhahah it would stop you if you were bigger level.
For example if bronze is set to reqlevel 1 at level 2 you would not be able to dig it :stuck_out_tongue: