Reputation: 319
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
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
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
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