messedupsongguy
messedupsongguy

Reputation: 319

In Unity, what type of method is Update()? And how to make my own?

How do gameobjects know that void Update means every frame and that OnCollisionEnter means when they collide. Can I make my own? Kind of like this

void OnPositionChange () {
 //code goes here
}

And then any script that has that OnPositionChange will recognize it and do something with it when the position changes.

Upvotes: 1

Views: 1860

Answers (4)

Hossein Rashno
Hossein Rashno

Reputation: 3469

Update(), Start() and other method with special function like these, are overloads from MonoBehaviour class. You can see all of your scripts are derived from MonoBehaviour class.

What you need is using Events. You can create an event and delegate and on special situation raise them so all your scripts that are register in that event can call their own method for that event.

Upvotes: 0

Reezoo
Reezoo

Reputation: 190

          float startPositionX;
          float startPositionY;
          float startPositionZ;
          float currentPositionX;
          float currentPositionY;
          float currentPositionZ;


            void start(){
            startPositionX = gameObject.transform.position.x ;
            startPositionY = gameObject.transform.position.y ;
            startPositionz = gameObject.transform.position.z ;
             }

            void update() {
            currentPositionX = gameObject.transform.position.x ;
            currentPositionY = gameObject.transform.position.y ;
            currentPositionZ = gameObject.transform.position.z ;
            OnPositionChange ();
            }


         void OnPositionChange () {
         if(startPositionX == ! currentPositionX ||
            startPositionY == ! currentPositionY || 
            startPositionZ == ! currentPositionZ){
            /*write your own code that you want to perform.*/ }
            }

Upvotes: 0

ゴスエン ヘンリ
ゴスエン ヘンリ

Reputation: 843

The BuiltIn SendMessage component: http://docs.unity3d.com/ScriptReference/Component.SendMessage.html

And this might help you for something, I guess: http://answers.unity3d.com/questions/676625/creating-my-own-custom-unity-messages.html

Here, the suggestion is to make a base class from which all objects that will need the method extends. In the example he used a damage source and damageable objects and example how they would interact:

In DamageSource.cs (the class you'd use to give damage to )

using UnityEngine;
 using System.Collections;

 public class DamageSource : MonoBehaviour {
     protected float damageAmount = 10f;

     //not 100% necessary, but handy for an example of how to 
     //handle damage based on the attacker (which is 
     //relevant for info sent in the OnTakeDamage() method
     protected ElementType elementType = ElementType.Normal;

     //we use a function for getting the damage this 
     //DamageSource can do because it lets us overwrite it.
     //Eg, if the enemy is weakened, you can factor that 
     //in and return a lesser amount of damage.
     public float GetDamageAmount() {
         return damageAmount;
     }

     public ElementType GetElementType() {
         return elementType;
     }
 }

 //kinds of elements available for damage / resistance calculations
 public enum ElementType {
     Normal,
     Fire,
     Ice,
     Lightning
 }

In DamageableObject.cs (the base class from which all damageable objects inherit):

using UnityEngine;
 using System.Collections;

 public class DamageableObject : MonoBehaviour {
     protected bool wasRecentlyHit;
     protected float health;
     protected float maxHealth;

     public void Awake() {
         health = maxHealth;
     }

     //Creating a virtual void method lets you choose whether 
     //or not you want to set it in a derived class.
     //Here, we track the amount of damage and the source 
     //the damage came from. This can sometimes be handy for 
     //context-sensitive reactions to being damaged. Eg, play 
     //a particular sound in damaging the player, when 
     //successfully damaged by a particular attack.
     //Note that this base implementation does nothing - you 
     //override it in an inheriting class, very similar to using Update() etc.
     protected virtual void OnTakeDamage(float damageAmount, DamageSource damageSource) {}
     //An example of how you'd check whether damage is incoming. 
     //You can alternatively just call 
     //someDamageableObject.TryDoDamage() from another script.
     public void OnTriggerEnter(Collider other) {
         DamageSource damageGiver = other.GetComponent<DamageSource>();
         if (damageGiver) {
             TryDoDamage(damageGiver.GetDamageAmount(),damageGiver.gameObject);
         }
     }
     public void TryDoDamage(float damageAmount, GameObject damageGiver) {
         //early out, this DamageableObject was damaged a very 
         //short time ago and shouldn't be damaged again so soon
         if (wasRecentlyHit) return;

         //optionally perform any damage calculations here based
         //on the damageGiver, eg more damage from the player 
         //being weakened somehow, or less damage from type 
         //resistances... etc.
         damageAmount = CalculateDamage(damageAmount,damageGiver);

         //if after our damage calculations we still have an 
         //amount of damage greater than 0, we do the damage and 
         //send the OnTakeDamage() message.
         if (damageAmount>0f) {
             health -= damageAmount;

             //optional handling of dying (uncomment this and the OnDeath() function to enable)
             //if (health<0f) {
             //    OnDeath(damageAmount,damageGiver);
             //}
             //else {
             OnTakeDamage(damageAmount,damageGiver);
             //}
         }
     }

     //Uncomment this and the (healtn<0f) if statement above 
     //if you want to handle dying as well as being damaged
     //protected virtual void OnDeath(float damageAmount, DamageSource damageSource);

     //Default implementation for calculating damage, 
     //given some amount of damage, and some source of damage.
     //Override this in an inheriting class if you want to do 
     //different damage, eg based on the damage source (2x 
     //damage from fire attacks, 0.5x damage from ice 
     //attacks... etc) or based on the DamageableObject's 
     //current state (eg, player is weakened, so takes 1.5x damage)
     protected float CalculateDamage(float damageAmount, DamageSource damageSource) {
         return damageAmount;
     }
 }

In PlayerDamageReceiver.cs:

using UnityEngine;
 using System.Collections;

 public class PlayerDamageReceiver : DamageableObject {

     //override the OnTakeDamage() method to make a 
     //different implementation of it for this class
     protected override void OnTakeDamage(float damageAmount, DamageSource damageSource) {
         Debug.Log("Ouch, the player was damaged!");
     }

     //Uncomment this to override the OnDeath() function 
     //in DamageableObject (if you've uncommented that, that is)
     //protected override void OnDeath(float damageAmount, DamageSource damageSource) {
     //    Debug.Log("Uhoh... The player died. :(");
     //}

     //override the CalculateDamage() function to 
     //determine how damage applies to the player
     protected override float CalculateDamage(float damageAmount, DamageSource damageSource) {
         //Example: give the player a 2x weakness to fire damage, and immunity to ice damage
         switch (damageSource.GetElementType()) {
             case (ElementType.Fire):
                 damageAmount *= 2f;
                 break;
             case (ElementType.Ice):
                 damageAmount = 0f;
                 break;
         }
         return damageAmount;
     }
 }

(I copied and paste the code from "nesis" user here, as asked by a fellow on comments)

Upvotes: 2

ali.turan
ali.turan

Reputation: 553

Actually you can do that. Simply you can make your own Behavior class.

public class MyBehavior : MonoBehaviour {

    Vector3 lastPosition = new Vector3();

    void Update () {
        Vector3 position = new Vector3();
        if (position != lastPosition)
        {
            OnPositionChange();
            lastPosition = position;
        }
        else
        {
            lastPosition = position;
        }
    }

    public virtual void OnPositionChange(){}
}

Now you define your script which inherits MyBehavior instead of MonoBehavior directly.

public class test : MyBehavior {

    public override void OnPositionChange()
    {
        Debug.Log("override");
    }

}

This is the closest thing to what you asked I belive.

Upvotes: 0

Related Questions