- Home /
Using method from main class in custom class
Hi ! I want to do something like that:
class A
{
public void A1()
{
B(); // I can't do that
}
}
class Tester : MonoBehaviour
{
A a;
void Start()
{
a = new A();
a.A1();
}
void B()
{
Debug.Log("nice");
}
}
How I can achieve that? Putting the same method B in class A just doesn't seem like right way to do that.
Answer by sparkzbarca · Jan 04, 2018 at 09:58 PM
your going to want to google whats called inheritence.
the jist of the answer is
Class A : monobehavior
{
Public void AI();
}
Class B : A
{
}
B Bexample;
Void update()
{
B.AI; // this is valid, B inherits from A, it is a kind of a and has all A's functions etc.
}
inheritence allows you to have a common base class of something and distinct children and they all have common features.
weapons for example
This is pretty code filled but basically you have this parent class, that's BaseMeleeWeapon, it has a function called attack. Now Sword and Spear are child classes, they inherit from it. Because of that a sword IS a BaseMeleeWeapon, a Spear IS a BaseMeleeWeapon. a sword is not a spear however or the other way around. But this means that if you put common stuff in it and in code instead of storing a spear as a spear you store it as a basemeleeweapon and refer to it that way, you can easily swap it out for a spear and all the code still works because both are of type basemeleeweapon.
A bool for example is actually just an integer and you can in fact treat a bool like an int, because it is one.
bool test;
int othertest;
othertest = test;
works
Because a bool inherits from int.
BaseMeleeWeapon : monobehavior
{
virtual void Attack();
}
Sword : BaseMeleeWeapon
{
Attack()
{
//insert here how a sword attacks
}
}
Spear : BaseMeleeWeapon
{
Attack()
{
//insert here the code for how a spear attacks
}
}
BaseSoldier : Monobehavior
{
BaseMeleeWeapon MeleeWeapon;
BaseMeleeWeapon SecondaryWeapon;
BaseMeleeWeapon EquippedWeapon;
void Start()
{
MeleeWeapon = new Sword();
SecondaryWeapon = new Spear();
EquippedWeapon = MeleeWeapon;
}
void EquipSecondary()
{
EquippedWeapon = SecondaryWeapon()
}
void WeaponAttack()
{
EquippedWeapon.Attack()
}
This code allows you to have multiple weapons, swap between them, have the right attack code executed and it's all fine, you can easily add a third weapon with it's own unique attacks or fourth and no change needs to be made to existing code, you just need new code really.
ok I see that this is working but I need to check exactly how. Thanks for extensive answer !
Answer by OneCept-Games · Jan 04, 2018 at 09:51 PM
class A
{
public void A1()
{
Tester b = new Tester();
b.B();
}
}
And don't forget to make your B() function public.
hmm, b = new Tester() will not start the awake, start etc methods ? If not it would not be so big and I could use that. I Assume there is no other way ?
here is actual code from my project showing an example of a base weapon class and it being inherited by a sword and used. This gives you an idea of what for example variables/functions all weapons should ahve in this case but it kind of shows how I tried to insolate the things I want all weapons to have and then inherit from Base class. So for example all weapons will have a damagetype a damage value a dps etc.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class $$anonymous$$eleeWeaponBase : $$anonymous$$onoBehaviour {
public enum DamageTypeEnum{Slashing,Piercing,Crushing,IgnoreArmor};
protected int Damage;
protected float AttackSpeed; //attacks per second
protected float DPS; //Damage per second
protected DamageTypeEnum DamageType;
protected GameObject Target;
protected bool $$anonymous$$ayAttack;
protected HitInformation HitInfo;
public GameObject WeaponTip;
// Use this for initialization
void Start () {
}
public struct HitInformation{
public DamageTypeEnum DamageType;
public int Damage;
public float $$anonymous$$eleeAttack;
}
public virtual bool Attack (float $$anonymous$$eleeAttack)
{
HitInfo.Damage = Damage;
HitInfo.DamageType = DamageType;
HitInfo.$$anonymous$$eleeAttack = $$anonymous$$eleeAttack;
PlayAttackAnimation ();
return true;
}
protected abstract void PlayAttackAnimation ();
}
This is an example of how a base weapon class doesn't care if the weapon is a sword for example or a spear. it also doesn't care what type of armor you have. You can see HP and such are assigned in this case, that's just default values basically. If you do
Swordsman : $$anonymous$$eleeFootBase
you can in that class override the values here
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class $$anonymous$$eleeFootBase : $$anonymous$$onoBehaviour {
public enum Team {Red,Blue};
public GameObject Weapon;
$$anonymous$$eleeWeaponBase $$anonymous$$eleeWeapon;
public GameObject Shield;
ShieldBase ShieldComponent;
float $$anonymous$$eleeWeaponAttack;
float $$anonymous$$eleeWeaponDefense;
ArmorBase Armor;
//int HP;
//float Speed;
//int UnitSize;
//float $$anonymous$$orale;
bool $$anonymous$$ayCharge;
float Charge$$anonymous$$odifier;
GameObject Target;
// Use this for initialization
void Start () {
$$anonymous$$eleeWeapon = Weapon.GetComponent<$$anonymous$$eleeWeaponBase> ();
ShieldComponent = Shield.GetComponent<ShieldBase> ();
//HP = 100;
//Speed = 1f;
//UnitSize = 10;
//$$anonymous$$orale = 100f;
$$anonymous$$eleeWeaponAttack = 1f;
}
bool Attack ()
{
return $$anonymous$$eleeWeapon.Attack ($$anonymous$$eleeWeaponAttack);
}
//void ReceiveDamage ();
//void $$anonymous$$ove (Vector3 TargetPos);
//void $$anonymous$$ove (Transform TargetObject);
// Update is called once per frame
void Update () {
if (Input.GetButtonDown ("Attack"))
Attack ();
}
}
and lastly here is an example of a sword. Some code has been omitted for brevity but you can see how an actual sword might be assigned, it inherits, it goes through and assigns values for all those stats like damage and such in Base$$anonymous$$eleeWeapon
It overrides the base classes attack PlayAttackAnimation code. So an object with a sword script attached will run a swords attack animation specifically. But you can see how with the base class from earlier, If I were to do
Spear : Base$$anonymous$$eleeWeapon
{
void Start()
{
Damage = 5;
DamageType = DamageTypeEnum.Piercing;
..
}
I could now have a sword and a spear and I could swap between them freely on a Base$$anonymous$$eleeFoot.
This line here
$$anonymous$$eleeWeapon = Weapon.GetComponent<$$anonymous$$eleeWeaponBase> ();
from the script Base$$anonymous$$eleeWeapon from last comment $$anonymous$$eans that it doesn't care if that melee weapon is a sword or if I write a whole new spear class or a new mace class or jedi light saber class, As long as I inherit those classes from $$anonymous$$eleeWeaponBase they are all melee weapons and I can just drop them into my $$anonymous$$eleeWeapon variable and it'll call the spear or lightsabers attack code ins$$anonymous$$d of the swords.
That's the power of inheritance.
This is a sword class, but remove the word sword for spear, change the values and attack function code to another and you have a new weapon ready for use with your melee foot soldiers, no change to existing code needed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sword : $$anonymous$$eleeWeaponBase {
Animator anim;
void Start () {
$$anonymous$$ayAttack = true;
Damage = 10;
DamageType = DamageTypeEnum.Slashing;
anim = GetComponent<Animator> ();
}
protected override void PlayAttackAnimation ()
{
anim.Play ("Attack",-1,0f);
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter(Collision collision)
{
}
void OnCollisionExit(Collision collision)
{
//anim.SetBool ("Collision", false);
}
}
I would advice you to take some tutorials on C# if you need to use scripts in Unity - and in most cases you do, and would quickly meet more complex problems that need to be solved.
You are right that calling class A from Tester, and then again call Tester from A is never a good idea. You should in this case consider isolating the B() function in a third class - as a kind of helper class where you pile up functions that you use often.
Thanks for fast answers. I will follow your advice and do some lessons before i will choose best solution for my problem.
This is a bad example as "Tester" in the question is a $$anonymous$$onoBehaviour which can not be created with "new". So this answer is misleading. Yes, "A" need to have a reference to an instance of the "Tester" class, but you can't create one on the fly. Components can only live on gameobjects.
Ahh, you are right @Bunny83, i missed that.
yea I try to balance my rigid will work code against kind of pseudo code.
In this case the new whatever was used consciously because I honestly thought "well he's not actually going to try to copy paste my random code"
It was designed more to showcase an example of how inheritance roughly works with bits of yes pseudo code basically ins$$anonymous$$d of 100% real code. I figured if he tried to do something he'd kind of write his own code and it'd be a little less exactly to my random code but my bad.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Passing a class instance to a method 1 Answer
How can I use something like Invoke() to call a method in another class? 1 Answer