- Home /
While loop yield lag?
I'm trying to make a script that when I use a melee attack, the player moves towards the enemy unless he is within a specific distance to him, and the enemy is also pushed back, regardless of position.
I got it to work.. the only problem is that it seems that because I have a nested while loop... It seems to have the first frame lag for a noticeable split-second before working as it should.
This lag is a problem, since I can't have the game lag every time the player wants to melee. Is there any reason besides a slow cpu that this would happen, I really doubt my computer wouldn't be able to handle this, and is there any way I can make it more efficient?
var cooldownTimer: float = 10.0; //This will be changed in inspector
var countDown : float = 0.0;
var playerAttackRange : int = 5;
var particle : GameObject;
var player : GameObject;
var particleClone = particle;
var slashDistance : float = 1.0;
var moveDirection;
var shouldMove : boolean = true;
var controller : CharacterController;
private var currentPosition : Vector3;
var swordSlash : AudioClip;
var hit : RaycastHit;
var hitLoc;
var impact;
var attackBool : boolean = false;
function Start () {
}
function Update () {
currentPosition = transform.position;
moveDirection = player.transform.forward;
if(Input.GetButton("Fire1") && Time.time > countDown){
attack();
}
}
function attack(){
if(AbilitySystem.fireElement.equippedFire == true) {
audio.PlayOneShot(swordSlash);
countDown = Time.time + cooldownTimer;
var fwd = transform.forward; // <- easier way to get the forward direction
if(Physics.Raycast(transform.position, fwd, hit, playerAttackRange)){
Debug.Log("Melee has struck " + hit.collider.name + " at a range of " + playerAttackRange +"!!!!!!!!!!!");
if(hit.collider.tag == "Enemy") {
hit.collider.GetComponent(EnemyHealth).enemyCurrentHealth -= AbilitySystem.fireElement.swordDamage;
particleClone = Instantiate(particle, hit.transform.position, hit.transform.rotation);
Destroy(particleClone, 1);
hitLoc = hit.point;
// calculate the direction to push the target:
impact = -hit.normal;
impact.y = 0; // keep it horizontal
impact.z = 0; // keep it 2d
impact = impact.normalized;
// apply the movement during duration seconds:
var duration = 0.25;
var durationTwo = duration;
while (duration > 0){
Debug.Log("While loop one started");
while (durationTwo > 0){
Debug.Log("While loop two started");
if(Vector3.Distance(transform.position, hitLoc) > slashDistance){
player.transform.Translate(impact.x * Time.deltaTime * 4, impact.y, impact.z, Space.World);
Debug.Log("Player transformed");
}
durationTwo -= Time.deltaTime;
Debug.Log("DurationTwo = " + durationTwo);
}
hit.transform.Translate(impact * Time.deltaTime * 4, Space.World);
Debug.Log("Enemy transformed");
duration -= Time.deltaTime; // count time
Debug.Log("Duration = " + duration);
Debug.Log("yielding");
yield; // return to loop next frame
}
}
}
}
}
It actually seems to lag more the farther away the player is from the enemy
Answer by Kryptos · Apr 11, 2012 at 10:12 PM
Your nested while
does not wait with a yield
statement. Try with:
while (duration > 0){
Debug.Log("While loop one started");
while (durationTwo > 0){
Debug.Log("While loop two started");
if(...){
...
}
...
Debug.Log("yielding");
yield; // return to loop next frame
}
...
Debug.Log("yielding");
yield; // return to loop next frame
}
But it seems that you want the two while
to be executed in parallel. You should consider using two coroutines (one for each while
).
How would I easily pass the required variables to the coroutines? The reason I did it this way was because I needed the variables gained from the RayCastHit