Using polymorphysm with objects in Unity.

Hey!
I created abstract class named “PowerUp” and few child classes like: BonusHeath, DoubleDamage, AmmoPack. Now I have objects in Editor with script to rotate power up’s:

[...]

    public PowerUp objectType;

    void Update () {
    	transform.Rotate (new Vector3(0f, 0f, Time.deltaTime * rotationSpeed));
    }

    void OnTriggerEnter(Collider collider){
    	if (collider.gameObject.tag == "Player") {
    	          //this.GameObject.FindComponent<nameofscript>().SendMessage ("OnPickup", 30,SendMessageOptions.DontRequireReceiver); //i dont' want to use this
                  myObject.OnPickup(); ///i want to use this
        	      Destroy(this.gameObject);
        
        }
    [...]

And I want to use polymorphysm (by using method OnPickup() which is implemented in every PowerUp class by overriding). How I can implement it good? I can’t use child script in parent’s place. I really need to create an empty object with component and call him to call OnPickup() ?

I think you mix up responsibilities. A script which is responsible to rotate an object shouldn’t detect OnTriggerEnter events. That’s just wrong. We don’t know the name of your script (since you didn’t post it) but you should write scripts based on it’s usage. A rotate script is a general purpose script and should look something like this:

public class AutoRotate : MonoBehaviour
{
    public Vector3 rotationSpeed = new Vector3(0,0,1);
    void Update () {
        transform.Rotate (rotationSpeed * Time.deltaTime);
    }
}

Such a simple script can be attached to any object and allows to automatically rotate around any axis at any speed.

Your PowerUp script has a different responsibility. You could do it like this:

public abstract class PowerUp : MonoBehaviour
{
    public abstract void OnPickup();
    void OnTriggerEnter(Collider collider)
    {
        if (collider.gameObject.tag == "Player") {
            OnPickup();
            Destroy(this.gameObject);
        }    
    }
}

A child class could look like this:

public class HealthPowerup : PowerUp
{
    public override void OnPickup()
    {
        // Do your health power up stuff.
    }
}

Hi, I’m not sure exactly how you are looking to use polymorphism but it is easily possible - we use it a lot. From your description you could abstract out the the Pickup to an abstract MonoBehaviour:

// This component cannot be added to gameobjects
public abstract class Pickup : MonoBehaviour
{
	public abstract void CollectAndApply();
}

Then inheriting from this you can have all your basic behaviour, for example all pickups may play the same visual effect upon being picked up.

public class BasePickup : Pickup
{
	public override void CollectAndApply ()
	{
		Debug.Log("All Pickups will call this if base.CollectAndApply is called");
	}
}

Now with that in place, you can implement all your child components to do specific behaviours:

public class HealthPickup : BasePickup
{
	public override void CollectAndApply()
	{
		base.CollectAndApply();
		Debug.Log("HealthPickup");
	}
}

All three components should be able to be used within scripts and serialised. GetComponent should be usable and having a public member variable should allow you to drag child components into the inspector. I hope that helps =D

So after writing class hierarchy I should:

1) Add component (script) rotating my object and checking for collisions
2) Add component (script) of **specific type** of collectable object (for example HealthPickup)
3) In OnTriggerEnter function in "RotationScript" write:

 GetComponent<HealthPickup>().CollectAndApply();

Am I understand it right or complicated something? xD

P.S.
Earlier I was trying to make one public Pickup field and add in editor HealthPack/AmmoPack/WhateverPack script there, but it was impossible. It’s the rule, yea? (name of script must be name of variable, you can’t add HealthPickup scipt to Pickup field?