Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Help accessing variables from other scripts for RPG stats c#

Discussion in 'Scripting' started by Collin__Patrick, Nov 13, 2015.

  1. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    This is my first time using the forums so forgive me if this thread is in the wrong spot.

    I am trying to create an RPG where each character has its own set of stats. I have run into a snag where I have to access variables from the players stat script when a battle starts and constantly use them until the battle has ended then clear those stats in case a different player collides with the enemy. I also have the problem of grabbing only the stat script of the player that collided with the enemy.

    I am not new to coding c# but everything that I know is self taught so please forgive me if its a mess or very basic. If you see anything else in the scripts worth changing please tell me for a lot of this has still not been tested.

    Player Stats Script
    using UnityEngine;
    using System.Collections;

    public class PlayerStats : MonoBehaviour {

    //Player Stats
    public static int health = 5;
    public static int str = 4;
    public static int spd = 7;
    public static int mag = 4;
    public static int agi = 8;
    public static int def = 2;
    public static int luk = 6;
    int level = 1;

    void Update () {
    LevelUp();
    }

    //players exp
    public int exp = 0;

    //amount of exp needed to level up
    int expCount = 10;

    void LevelUp()
    {
    if (exp == expCount) {
    //speed stat is un affected because it's used outside of battle
    //stats very depending on characters
    level += 1;
    str += 1;
    mag += 1;
    agi += 1;
    def += 1;
    luk += 1;
    health += 1;
    exp = 0;
    expCount += 5; //should change to exponential growth
    }
    }
    }



    Battle Cycle
    using UnityEngine;
    using System.Collections;

    public class BattleCycle : MonoBehaviour {

    bool win = false;
    bool lose = false;
    bool battle = false;

    public GameObject player;

    void Update() {

    }

    void OnCollision() {
    battle = true;
    }

    void Start() {
    //can turn looping on or off
    while (battle == true) {
    //(Player attack animation)
    enemyHealth -= (playerDamage - enemyDefence / 2);
    HealthCheck();
    //(Enemy attack animation)
    playerHealth -= (enemyDamage - playerDefence / 2);
    HealthCheck();
    }
    }

    void HealthCheck() {
    //checks player health
    if (playerHealth >=0) {
    //loses the battle
    battle = false;
    Lose();
    }

    //checks enemy health
    if (enemyHealth >= 1) {
    //wins the battle
    battle = false;
    Win();
    }

    //ends battle and kills player
    if (lose == true) {
    //destroy the player here
    }

    if (win == true) {
    //ends battle scene and returns to battle field
    ;
    }
    }

    void Win() {
    //plays win animation and ends the battle
    //(Play win animation)
    WaitForSeconds (3);
    Win = true;
    }

    void Lose() {
    //plays lose animation and ends the battle
    //(Play lose animation)
    WaitForSeconds (3);
    Lose = true;
    }

    //use if turn looping is off
    void End() {
    //ends battle scene

    }

    int playerHealth {
    //grabs the players Heath from the statistics script
    }

    int playerDamage{
    //grabs the players str from the statistics script
    }

    int playerDefence{
    //Grabs the players def from the statistics
    }

    int enemyHealth{
    //grabs the enemy's health from the statistics script

    }

    int enemyDamage{
    //grabs the enemy's str from the statistics script

    }

    int enemyDefence{
    //grabs the enemy's def from the statistics script

    }
    }
     
  2. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    So when you put a script on a GameObject that script becomes a component of that GameObject. If you want to access that script component on that GameObject first you need to get the GameObject in the class that needs to get the variables.

    Class level
    private GameObject myGameObject;

    In the start method put
    myGameObject = GameObject.Find("Character");

    The "Character" is the name of the GameObject that you named it in the inspector window.

    There are different ways of getting the GameObject btw
    After you get the appropriate GameObject you can get the the script component.

    put your script component class level
    private PlayerMovementAndInput playerMovementAndInputScript;

    PlayerMovementAndInput is the name of the script and the name of its class

    Then in the start method put
    playerMovementAndInputScript = myGameObject .GetComponent<PlayerMovementAndInput>();

    Then you can access the public variables of that script thats a component of the GameObject

    Example
    bool isWalking = (Mathf.Abs(playerMovementAndInputScript.horizontalInput) + Mathf.Abs(playerMovementAndInputScript.verticalInput)) > 0;

    Hope that helps you
     
    Last edited: Nov 13, 2015
  3. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    I am getting an error, "Assets/Scripts/BattleCycle.cs(17,26): error CS0236: A field initializer cannot reference the nonstatic field, method, or property 'BattleCycle.playerStats' "

    This is the changed script:

    using UnityEngine;
    using System.Collections;

    public class BattleCycle : MonoBehaviour {

    bool win = false;
    bool lose = false;
    bool battle = false;

    public int enemyHealth = 1;
    public int enemyDef = 1;
    public int enemyStr = 1;

    private GameObject myGameObject;
    private PlayerStats playerStats;


    int playerStr = (playerStats.playerStr);
    int playerDef = (playerStats.playerStr);
    int playerHealth = (playerStats.playerStr);


    void Update() {

    }

    void OnCollision() {
    battle = true;
    }

    void Start() {
    myGameObject = GameObject.Find("Player1");
    playerStats = myGameObject .GetComponent<PlayerStats> ();

    //can turn looping on or off
    while (battle == true) {
    //(Player attack animation)
    enemyHealth -= (playerStr - enemyDef / 2);
    HealthCheck();
    //(Enemy attack animation)
    playerHealth -= (enemyStr - playerDef / 2);
    HealthCheck();
    }
    }

    void HealthCheck() {
    //checks player health
    if (playerHealth >=0) {
    //loses the battle
    battle = false;
    Lose();
    }

    //checks enemy health
    if (enemyHealth >= 1) {
    //wins the battle
    battle = false;
    Win();
    }

    //ends battle and kills player
    if (lose == true) {
    //destroy the player here
    }

    if (win == true) {
    //ends battle scene and returns to battle field
    ;
    }
    }

    void Win() {
    //plays win animation and ends the battle
    //(Play win animation)
    WaitForSeconds (3);
    Win = true;
    }

    void Lose() {
    //plays lose animation and ends the battle
    //(Play lose animation)
    WaitForSeconds (3);
    Lose = true;
    }

    //use if turn looping is off
    void End() {
    //ends battle scene

    }

    /*int playerHealth {
    //grabs the players Heath from the statistics script
    }

    int playerDamage{
    //grabs the players str from the statistics script
    }

    int playerDefence{
    //Grabs the players def from the statistics
    }

    int enemyHealth{
    //grabs the enemy's health from the statistics script

    }

    int enemyDamage{
    //grabs the enemy's str from the statistics script

    }

    int enemyDefence{
    //grabs the enemy's def from the statistics script

    }*/
    }

    Also, Is there a way that I could give all of the characters a "player" tag but when they collide with an enemy it only takes variables from the script of that player and not any player with that tag?
     
    Last edited: Nov 13, 2015
  4. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    Sure you can do that but it's important to distinguish a game objects name and it's tag. Each player should have a different name even if the only difference is a number appended at the end. So if a player collides with an enemy check of the enemy has the appropriate name if so then executive. I can elaborate more if you need when I'm home.
     
  5. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    Do you know what I can do about the error i'm getting?
     
  6. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    Delete
     
    Last edited: Nov 13, 2015
  7. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    Also this ^ Should not be in the same class level. You cannot get playerStats in that scope.

    Put this class level

    int playerStr;
    int playerDef;
    int playerHealth;


    And this in your start method after you set playerStats

    playerStr = playerStats.playerStr;
    playerDef = playerStats.playerStr;
    playerHealth = playerStats.playerStr;
     
  8. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    Oh i see what else is going on in your playerstats scirpt get rid of this

    public static int health = 5;
    public static int str = 4;
    public static int spd = 7;
    public static int mag = 4;
    public static int agi = 8;
    public static int def = 2;
    public static int luk = 6;

    and put this

    public int health = 5;
    public int str = 4;
    public int spd = 7;
    public int mag = 4;
    public int agi = 8;
    public int def = 2;
    public int luk = 6;
     
  9. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    you cant access static variable in the object. Remember a static variable belongs to the Class and non static variables belong to the child objects of the class.
     
  10. Collin__Patrick

    Collin__Patrick

    Joined:
    May 20, 2015
    Posts:
    188
    Thanks! I had to remove the static off of the variables I was trying to pull. I hope that doesn't screw anything up. other than that no errors!

    When you have the chance get back to me with the collision tags details.
     
  11. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    Glad that helped! Its fine to use static variables but keep in mind that static variables belong to the class not any of the derived objects. If you wanted to do this

    public static int health = 5;
    public static int str = 4;
    public static int spd = 7;
    public static int mag = 4;
    public static int agi = 8;
    public static int def = 2;
    public static int luk = 6;

    Then you would access them like this

    int getHP = PlayerStats.health;

    I would advice against keeping that many stats static though try and keep your scripts as object oriented and modular as possible.
     
  12. Warsymphony

    Warsymphony

    Joined:
    Sep 23, 2014
    Posts:
    43
    So lets say you have a player and an enemy and you want to check if they collide.

    Make a script put it on your enemy as a component.

    Add this method to the script, it will be called for you if it has a Collider component.

    void OnCollisionEnter(Collision target)
    {
    if (target.gameObject.tag == "Player")
    {
    Debug.Log("Collided!");
    }
    }

    Also read up on Rigidbody's and its settings like Sleeping Mode and Collision Detection.

    Also read up on the different types of OnColllision methods.
    http://docs.unity3d.com/ScriptReference/Collider.OnCollisionEnter.html

    And! Pay close attention to the Collider components setting Is Trigger, this bool will change what OnColllision method to use.

    GL