Tween not firing consistently

Hello!

I have been setting up an infinite jumping game. I am randomly spawning platforms at the top of the screen and tweening them down based on the other platforms that are already within the game. The problem is that the tween only fires sometimes. I am going to link the section of code that is causing the issues as well as my project.

the project: https://playcanvas.com/project/821647/overview/tweennotfiring

the script where the tween will not fire every time:

PlatformManager.prototype.spawnPlatform = function(){
        //adds this newly spawned platform to the array
        var platformObject = this.createPlatformEntity("platform1");
        //sets its position to the spawn height
        let spawnPosition = this.app.root.findByName("platformSpawnHeight").getPosition();
        spawnPosition.x = this.randomFloatFromInterval(-1,1);
        platformObject.platformEntity.setPosition(spawnPosition);
        
        //gets the inverse of the alpha because you need how much is left
        //in the tween not how much has passed. 
        var inverseTweenAlpha = 1 - this.tweenAlpha;

        //gets ending position from spawn and the distance multiplied by the inverse alpha
        let endingPosition = new pc.Vec3(spawnPosition.x,Math.abs(spawnPosition.y - this.tweenDistanceFromPlatToLowerBound*inverseTweenAlpha),spawnPosition.z);
        
        //gets length for the inverse alpha and the normal tween length
        var partialTweenLength = this.tweenLength*inverseTweenAlpha;
    
        ///////THIS TWEEN IS INCONSISTENT
        platformObject.platformTween = platformObject.platformEntity.tween(platformObject.platformEntity.getLocalPosition())
            .to(endingPosition, partialTweenLength, pc.QuadraticOut)
            .delay(0)
            .loop(false)
            .yoyo(false)
            .start();
    
        //pushes the new object that is being tweened onto the array that holds all the platform objects
        this.platformObjectTracker.push(platformObject);
};

And here is a video of the issue. If you watch the top of screen, you will see that a platform doesn’t get tweened after being spawned every once in awhile at the top of the screen. Then it moves again once the character jumps because it is being swept up by the function that loops through all of the platforms in the array to move them all together every time we jump. I just can’t seem to figure out why this tween won’t always fire. The tween length and ending positions don’t seem out the ordinary when they are being console logged. Note that the camera is a bit more zoomed out than it will be in the final game so that the spawned platforms can be seen.

Hi @Jake_Johnson

Based on just a quick look, if I had to guess it is because the character starts another jump before the initial tween has ended, causing the spawn tween and the function that moves everything down the screen together to fight against one another. With the objects being created dynamically, it might be hard to test, but you could always build a quick static scene with jumps that occur in quick succession to test this hypothesis.

@eproasim

I wish it was that simple but I believe I am manually stopping tweens before starting another one in the function that moves everything down the screen together so they should never be fighting against each other. In the platform object there is a slot for a tween so I always have the reference.

Hi @Jake_Johnson

Another quick look at the code, and I see a bit of a curiosity. I see that when you’re defining your tweens you include .start() in them. Does removing that from the definition and then calling .start() on the tween object manually, outside of the definition help? Can’t speak confidently, but it could have the possibility of soem tween fighting.

@eproasim

No that didn’t fix the issue either. I don’t think that should matter because the tween documentation says you can chain tween methods together. Its especially odd because I can confirm that the lines in the spawnPlatform function before the tween definition and the lines after the tween all execute 100% of the time.

Could it be something like the following. In your for loop you are checking i < this.platformObjectTracker.length, but within the loop you are pushing a new object to the array, which under some circumstances the tween gets stopped in the “else” part within the loop?

@Kulodo133

That is the odd thing as well. I can completely remove the .stop(); from the entire application and I will still have the same issues. I only really have the .stop(); to make sure there aren’t any issue but im not really sure they are necessary since I am overriding the tween. Both tweens are moving the platforms so why would it abruptly stop when a tween was being passed off.

Actually that isn’t completely true. The problem gets worse if I remove the stop(); commands. I guess that is an extra data point though I’m not sure it is useful.

@yaustar @will

Would one of yall be willing to give this a look? Been working on a it for a couple days without progress. If I console log the distance of the tween and the length of the tween it seems like there is some noise coming through with the distance value that is causing this but I can’t figure out where its coming from for the life of me.

It is a bit hard to understand what is happenning in your code, but I would recommend to limit the number of spawned platforms. It seems that you are spawning platforms inifintely, and on every jump applying a tween on each of them. After a few jumps you probably have a 100 of platforms that you are tweening, even though they are not visible. This becomes expensive pretty fast and can probably mess with your positions readings in large loops accessing an old context.

You have like 10-15 platforms visible on screen at most at any given point. Create them all in an array at the game start and place offscreen. This is your platforms pool. When you need to spawn a platfrom, take it from the pool, position where it needs to be and tween. Once a platform is out of screen, return it to the pool and reset it (like counters or any custom properties you attach to them). This will be much more manageable.

@LeXXik
Thanks for the response. I’ll go and do that now, but I would note I’ve been able to get this glitch to occur within the first few seconds before, meaning that there were around 10-15 in the platform array anyway.

Just to add a bit of context to what is happening in the code…
Essentially there are two ways that a platform moves. There is a large scale tween of all platforms whenever the player jumps up at a certain height on the screen. While these are moving, new platforms are spawned and immediately tweened to appear as if they were part of the group all along. These spawned platforms are added to an array of all platforms. I was going to destroy platforms after they got off screen but hadn’t gotten around to it yet.

I noticed that sometimes a platform can go down, then upwards. It means there is some condition, when the target position vector takes incorrect values. The tween then correctly moves the platform into incorrect position. You want to dig there.

1 Like

Yea I had mentioned that previously. the ending position is getting noise from somewhere but I can’t pinpoint where.

Also I’m not sure its that its actually going up but that everything around it is going down so it looks like its drifting against it because the only point of reference from the camera’s perspective is how the plats move. I’ve clamped that distance value to never go below 0 before and it still looks like it is going up.

You’re right though I’ve probably over complicated this not using a pool of platforms and instead making this creation and deletion system.

Hi,

I think you need to reset this.tweenAlpha to 0 each time in tweenPlatforms().

            if(i === 0 ){
                var current = 0;
                this.tweenAlpha = 0;  // like this
2 Likes

Sorry, it’s a large enough project that we can’t spend a couple of hours helping you debug.

If you can isolate the issue into something less complex and easily shows the issue, we are more likely to be able to help.

1 Like

@Kulodo133

Wow that did fix it I guess that is where the noise was coming from. Thanks so much man. How did you go about finding that?

@yaustar

I’ve got it now but I’ll be sure to condense it more next time. I realize that was a big request. As always, thanks so much for all the help yall consistently give.

1 Like

@Jake_Johnson I noticed that tweenAlpha was used to calculate the end vector and the length so I wondered how it could get the wrong values. I saw that that the tween.stop() calls for the i===0 tween would leave the tweenAlpha with whatever value it had at that moment, and then the next spawn tween would use that value for the first spawned tween. You might also want to see if you can recycle the alloced tweens, it looks like they will currently all get alloced again on every jump, and never destroyed.

2 Likes