NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: [Unity 3D] Jak dostat metody z třídy získané přes MonoScript.

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Garrom Orc Shaman:23.12.2016 18:40

Ahoj všichni. Mám skript targetController­.cs který se stará o HP a také určuje že objekt ke kterému je přiřazen jde trefit blastrem nebo raketami (ostatní objekty jsou ignorovány). Ovšem každý objekt má svůj vlatní controller.cs (např. UnguidetMissle­Controller.cs, PlayerShipCon­troller.cs nebo AsteroidContro­ller.cs).
Tyto "osobní" skripty metodou OnDeath určují co se s objektem stane pokud mu dojdou HP. problém je v tom že o HP se stará targetController­.cs.
Jsem schopen pomocí třídy UnityEditor : MonoScript a metody GetClass() získat typ cotrolleru aktuálního objektu. Controller aktuálního objektu ručně přiřadím k targetController. potřebuji vědět jen jednu věc.

  1. Jak dostat referenci na skript přiřazený jako MonoScript pomocí metody GetComponent().

bylo by skvělé kdyby to šlo nějak takhle :

public MonoScript objectController;
Type con;
void Start () {
        con = objectController.GetClass();
        GetComponent<con>().OnDeath()
}

bohužel to nejde ....

Odpovědět
23.12.2016 18:40
Life for Code, Code for Life. I chose my path, I should stick on it.
Avatar
D0ll0k
Člen
Avatar
D0ll0k:23.12.2016 19:31

Pokud voláš čistě metodu GetComponent(), voláš ji na GameObject, ke kterému máš přiřazený tento script, je to stejné jako kdyby jsi napsal:

this.GetComponent<TvojeTrida>();

Aby jsi mohl volat metodu na skript, který je na jiném GameObjectu, nejprve si ho musíš uložit a pak z něj dostat skript:

GameObject target;

target.GetComponent<TvojeTrida>().OnDeath();
// nebo
TvojeTrida trida = target.GetComponent<TvojeTrida>();
trida.OnDeath();
Nahoru Odpovědět
23.12.2016 19:31
Veni, vidi, programmato
Avatar
Odpovídá na D0ll0k
Garrom Orc Shaman:23.12.2016 21:58

Problém je v tom že ta "TvojeTrida" je nějaká třída... a já potřebuji zjistit jakou třídu tvoří proměnná typu MonoScript. Až budu mít referenci na tuto konkrétní třídu (jejíž typ je jiný, záleží na skriptu který v inspektoru přiřadím do veřejné proměnné) bude extrémně snadné na ní cokoliv volat. To co nazýváš <TvojeTrida> může být jakákoliv třída přiřazená v inspektoru... může to být cokoliv, třeba AsteroidContro­ller.cs nebo RocketController.cs problém je v tom že skript vlastně neví jaká třída to je a já nemůžu jednoduše napsat

GetComponent<SameClassAsInMonoScriptVariable>()

Už chápeš ? Problém není v tom dostat referenci na třídu, problém je v tom zjistit na jakou třídu mám dostat referenci.

Nahoru Odpovědět
23.12.2016 21:58
Life for Code, Code for Life. I chose my path, I should stick on it.
Avatar
Garrom Orc Shaman:23.12.2016 22:48

Vyřešeno, použil jsem dědičnost. Třída targetController je nyní parrent všech ostatních controllerů což znamená že mohu napsat

GetComponent<targetController>()

...TargetCpntroller sice v daném objektu nebude ale za to tu bude jeho child což je pro získání reference dostačující.

Akceptované řešení
+5 Zkušeností
Řešení problému
Nahoru Odpovědět
23.12.2016 22:48
Life for Code, Code for Life. I chose my path, I should stick on it.
Avatar
D0ll0k
Člen
Avatar
Odpovídá na Garrom Orc Shaman
D0ll0k:23.12.2016 22:53

Jasně... No, jestli jsou skripty AsteroidController a RocketController součástí prefabu, můžeš si vytvořit další třídu a pojmenovat ji třeba HealthManager. Tu budeš hledat pomocí GetComponent(). Zde si můžeš ukládat stav životů atp. Taky na ni budeš volat metodu OnDeath(), kde pak GameObject zničíš, nebo TakeDamage() pokud střely/údery nezabijí Asteroid či Rocket na jeden úder.

Pak je tu další možnost, že si žádnou třídu vytvářet nebudeš, ale budeš zjišťovat, jestli GameObject má daný skript:

if (target.GetComponent<AsteroidManager>() == null)
{
        // gameobject nemá skript AsteroiManager
}
else if(target.GetComponent<RocketController>() == null)
{
        // nemá ani RocketController
}
else
{
        // zasáhl jsi něco jiného
}
Nahoru Odpovědět
23.12.2016 22:53
Veni, vidi, programmato
Avatar
D0ll0k
Člen
Avatar
Odpovídá na Garrom Orc Shaman
D0ll0k:23.12.2016 22:54

Ok, i to je možnost

Nahoru Odpovědět
23.12.2016 22:54
Veni, vidi, programmato
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.