How to change property of another object?

Asked

Viewed 1,138 times

1

I have a screen with two 2d objects: player and enemy, both are prefab of an object called fighter.

They have three properties: attack, defense and hp.

I created a script and included in the camera, it is who will control the game.

I want to know how to make the camera script decrease the hp of one of my objects.

Class fighter:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class fighter: MonoBehaviour {

    public int attack;
    public int defense;
    public int hp;
    public int mp;

    // Use this for initialization
    void Start () {
        int range = Random.Range (150, 200);
        attack = range;
        range = Random.Range (100, 150);
        defense = range;
        range = Random.Range (800, 1000);
        hp = range;
    }

    // Update is called once per frame
    void Update () {

    }
}

Class that’s on camera:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class turnBased : MonoBehaviour {

    private BattleStates currentState;

    // Use this for initialization
    void Start () {
    }

    void Update() {
    }

    void OnGUI(){
        if (GUILayout.Button ("ATTACK")) {
        //crio um botão e ao ser clicado, deve causar dano ao inimigo
        enemy.hp -= 10; //<<<<aqui deve vir o código
        }
    }
}
  • 1

    Colleague, your question is not at all clear (but it was not I who denied it, okay?). First, what is the name of the class these objects use? It is fighter really? If yes, you tried to do player.GetComponent<fighter>().hp = 2;, for example? Put snippets of your code, otherwise no one will be able to help you.

  • @Luizvieira changed. I hope you can help better now. hug.

2 answers

5


You need to have a local reference for the objects you want to manipulate. There are several ways to get this reference:

  1. You can create two public objects of the type fighter and assign, via Unity editor (select and drag the player or enemy objects to the class attribute turnBased in the inspector, while the camera is selected).
  2. You can search for objects internally, using tags or object type (if different) or by name.

If you have two objects that are fixed, method 1 is the best. In fact, it is the one most used and advised in Unity trainings. But I will illustrate with method 2, using the name of the objects to find them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class turnBased : MonoBehaviour {

    private BattleStates currentState;

    public fighter player;

    public fighter enemy;

    // Use this for initialization
    void Start () {

        GameObject obj = GameObject.Find("player");
        if(obj != null) {
            player = obj.GetComponent<fighter>();
            if(player == null) {
                Debug.LogError("Objeto 'player' não tem o componente 'fighter'");
            }
        }
        else {
            Debug.LogError("Não encontrei objeto com o nome 'player'");
        }


        obj = GameObject.Find("enemy");
        if(obj != null) {
            enemy = obj.GetComponent<fighter>();
            if(enemy == null) {
                Debug.LogError("Objeto 'enemy' não tem o componente 'fighter'");
            }
        }
        else {
            Debug.LogError("Não encontrei objeto com o nome 'enemy'");
        }
    }

    void Update() {
    }

    void OnGUI(){
        if (GUILayout.Button ("ATTACK")) {
        //crio um botão e ao ser clicado, deve causar dano ao inimigo
        enemy.hp -= 10; //<<<<aqui deve vir o código
        }
    }
}

Also, here are other tips:

  • Do not add the game control script to the camera. Create an empty object (empty), perhaps called "gameController", for example, and add this script there. The camera should only have code related to camera things (translations, rotations, zooms, following character, etc).
  • Do not change the enemy’s (or player’s) HP directly from the control class. Invoke a "Take Damage" method (something like takeDamage) passing the total damage. Or make the attribute public hp become a real estate (with getter and Setter). Thus you have more control over what happens when damage is received directly in the interested class, and can do other things (touch animations, for example).
  • Luiz, it worked, yes, but I was left with a doubt: how to assign objects fighter at runtime? Let’s say I have 5 of them. When the player clicks on one, it is assigned automatically.

  • 1

    I don’t know what you mean by "assign". But if the idea is to add the component (script) fighter to an object, just use objeto.AddComponent<fighter>();. See the documentation of AddComponent. You need to understand the component and object distinction well in Unity, or explain yourself better.

1

As answered, there are several paths, but it would be good to avoid whenever possible using the means that involve search (Findobjectoftype, Findgameobjectswithtag, Sendmessage, etc) for a performance issue.

You can declare a variable "target public Gameobject" within the Fighter class and there in the scene drag the player to the variable "target" of Enemy via inspector and vice versa.

If the "targets" are changing/varying, you can create a method in the newly instantiated enemy that informs the player that it is your new target.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.