- Home /
Cant add a script as component. Type is derived by base class
Hej,
I'm working on a problem and yes i searched a bit.
My player is able to receive different 'conditions'. A condition is a class derived from the base class Condition.
So for example the condution Stone derives from Condition.
Here is the code to add the condition:
using UnityEngine;
using System.Collections;
public class AddCondition : PlayerTrigger {
// the condition we want to add
public Condition c;
// the players SpriteRenderer
private SpriteRenderer playerSpriteRenderer;
public override void Enter (GameObject _player, Rigidbody2D _playerRB)
{
// check if there are other conditions and remove them
Destroy(_player.GetComponent<Condition>());
// get the sprite renderer of the player
playerSpriteRenderer = _player.GetComponent<SpriteRenderer> ();
// play the change animation
// TODO
// change the sprite
playerSpriteRenderer.sprite = c.image;
// change the players mass
_playerRB.mass = c.mass;
// add the condition itself
_player.AddComponent<c>();
}
}
but it says error CS0118: 'AddCondition.c' is a 'field' but a 'type' was expected
i tried c.name, c.GetType() and typeof(c).
The trigger is a gameObject which has the above script attached. And the field c is obviously the derived class I want to add to the players gameObject and is set in the inspector.
i believe i saw some code that does this but i cant find it anymore :(
sidenote: i worked for many years as a Java and PHP / JS developer now so I habe to rethink a lot a my programing paradigms like this one. I think the compiler does now the type of component i want to add, its either condition or a derived class of it, And i dont know how to implement generics in this class since it derives itself from a class "PlayerTrigger" which checks if a collision is caused by the player and works as an interface with some overloaded methods and provides some variables for me, like the player object etc.
Thanks in advance :)
Answer by meat5000 · May 09, 2016 at 10:23 AM
If you want c to be a Class of Type Condition why do you not declare it like a class?
public Condition c = new Condition(); //(You class should have a constructor)
AddComponent is for adding MonoBehaviour derived scripts.
Condition derives from $$anonymous$$onoBehaviour. And all condtions like "stone" "feather" derives from Condition. So $$anonymous$$onoBehaviour -> Condition -> [Stone, Feather etc.]
And i cant create a new instance, the script above is a trigger (and a prefab). So i place it in the gameworld, assign a derived condition to the gameobject and if the player hits that trigger i want the assigned condition be also assigned to the player. I guess the problem is that "c" is a defined object. All i want is to add the same kind of it to the player but as i said: neither c.GetType(), c.name nor typeof(c) works :-/
Now i use a workaround and switch on c.name ......
When you add a component you need a type inside the "", where you've got a variable (same as in generic Java code, I believe). Also, note that AddComponent
creates the component.
So, for example, to add a Stone condition you'd need to do
c = _player.AddComponent<Stone>();
This creates the component, attaches it to the GameObject, and returns a reference to it. Its Awake()
method will be called too, if there is one.
And only after having made this call would you be able to use that instance of Stone
.
I suspect actually that you want to rethink your structure.
If I'm understanding things right, I don't think I'd implement these "Conditions" as Components of the object.
If they need to be $$anonymous$$onoBehaviours then I'd probably make them children of the object (which you'd do by instantiating the prefab and setting the parent of that instance's transform), and have the object maintain a list of what Conditions it has (you could do that kind of thing by searching the transform's children but it'd be more efficient to maintain a list).
Another way would be to try to copy the component from the Condition prefab to the object that needs it, but it would get a lot more complex I$$anonymous$$O. See for example http://answers.unity3d.com/questions/458207/copy-a-component-at-runtime.html or http://answers.unity3d.com/questions/643537/c-adding-components-from-other-gameobjects.html where there's also some stuff about the structure I advocated above,
thanks for your input. it doesn't matter if it is the same instance of the the object or a new. But i need to tag the player that it has now the stone condition. $$anonymous$$y idea was that i add the trigger object to the world, assign the condition the player should get and assign it after he enters the trigger, without the need to know which condition this trigger adds. Therefore it has the Condition c;
variable. But since there are only 6 different conditions i think i might go with a switch statement ;) like switch(c.name) { case "Stone": newCond = new Stone(); ...... } _player.AddComponent<newCond>();
Answer by Bunny83 · May 09, 2016 at 11:37 PM
Well, as other have already said your "c" variable hold a Condition "instance" and AddComponent expects a "Type". Components can't be "moved" to other gameobjects or attached / detached after they have been created.
So if you just want to add a new instance of the same component as you have stored in your c variable, you just have to do this:
_player.AddComponent(c.GetType());
This will add the same class that the c variable is referencing to your player. The generic method only works with actual types at compile time. So you have to use the AddComponent variant that takes a System.Type object instead.
not even copied? as I said there are a lot of different things in unity. little subtile changes in the way you would approach a problem on standalone programm. like undetachtable components. I'm sure this has to do with performance reasons but anyway :D
Your answer
Follow this Question
Related Questions
Creating a Script at runtime, and adding it to an object... 1 Answer
Unity 5 C#, having a script show up in a path in the Editor 1 Answer
How to get ANY component type 2 Answers
C# string as type for AddComponent 2 Answers
How to execute a method when I create a new script, or I saved an existing one ? (and get his type) 2 Answers