问题
My goal is to make a single collision detection that will decrease the movement speed of the object it collided with for a specific duration.
What I tried so far:
//Class that detects the collision
if (other.gameObject.tag == "enemy")
{
EnemyMovement enemyMove = other.GetComponent <EnemyMovement> ();
if (enemyMove.slowMove != 1) {
return;
}
enemyMove.Slow (2, 0.5f, true);
//....
//Class that handles the Enemy-Movement
//The slowfactor gets multiplied with the Vector3 that handles the movementspeed of the Character
void FixedUpdate ()
{
Movement();
}
void Movement()
{
gegnerRigid.MovePosition (transform.position + (gegnerMove * slowMove));
}
public void Slow (float duration, float slowFactor, bool slowed)
{
if (slowed)
{
if (duration > 0) {
duration -= Time.deltaTime;
slowMove = slowFactor;
Slow (duration, slowFactor, slowed); //this recursive Call leads to huge performance issues, but how to keep the function going?
} else {
slowMove = 1;
slowed = false;
}
}
}
So what I wanted to happen: Call the Slow-function if collision happens and make it invoke itself until the duration is 0.
回答1:
Note, the key here is that
1. You have the buff/unbuff on the other object.
You just call to the other object from the 'boss' object. Do not put the actual buff/unbuff code in your 'boss' object. Just "call for a buff".
In other words: always have buff/unbuff code on the thing itself which you are buffing/unbuffing.
2. For timers in Unity just use "Invoke" or "invokeRepeating".
It's really that simple.
A buff/unbuff is this simple:
OnCollision()
{
other.GetComponent<SlowDown>().SlowForFiveSeconds();
}
on the object you want to slow...
SlowDown()
{
void SlowForFiveSeconds()
{
speed = slow speed;
Invoke("NormalSpeed", 5f);
}
void NormalSpeed()
{
speed = normal speed;
}
}
If you want to "slowly slow it" - don't. It's impossible to notice that in a video game.
In theory if you truly want to "slowly slow it"...
SlowDown()
{
void SlowlySlowForFiveSeconds()
{
InvokeRepeating("SlowSteps", 0f, .5f);
Invoke("NormalSpeed", 5f);
}
void SlowSteps()
{
speed = speed * .9f;
}
void NormalSpeed()
{
CancelInvoke("SlowSteps");
speed = normal speed;
}
}
It's that simple.
来源:https://stackoverflow.com/questions/40912214/recursive-call-to-buff-unbuff-c-sharp-unity3d