jump/fall/land animation consistency fixes
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-09-10 13:24:14 -04:00
parent 797dfc95f6
commit 44b70f4ce6
8 changed files with 126 additions and 48 deletions

View File

@ -15,7 +15,6 @@
Ticketed randomizer node for BTs to more heavily weight attacking and waiting
+ bug fixes
Fix jump/fall/land animations being buggy and inconsistent between client/server
Fix empty item slot not showing underneath dragged item
Fix grass rendering distance

View File

@ -713,6 +713,9 @@ Fix server ground movement tree playing animation over falling animation
Fix cursor visuals
3D spline implementation
(09/10/2024)
Fix jump/fall/land animations being buggy and inconsistent between client/server
# TODO

View File

@ -66,10 +66,6 @@ public class ServerGravityTree implements BehaviorTree {
if(state == GravityTreeState.NOT_ACTIVE){
frameCurrent = 0;
}
ServerFallTree fallTree;
if((fallTree = ServerFallTree.getFallTree(parent))!=null){
fallTree.start();
}
}
public void interrupt(){

View File

@ -68,18 +68,23 @@ public class ClientFallTree implements BehaviorTree {
@Override
public void simulate(float deltaTime) {
switch(state){
case ACTIVE:
if(ClientGravityTree.getClientGravityTree(parent) != null && !ClientGravityTree.getClientGravityTree(parent).isActive()){
this.land();
break;
}
if(frameCurrent > 0){
stateTransitionUtil.simulate(FallState.ACTIVE);
}
frameCurrent++;
break;
case INACTIVE:
break;
case ACTIVE: {
if(ClientGravityTree.getClientGravityTree(parent) != null && !ClientGravityTree.getClientGravityTree(parent).isActive()){
this.land();
break;
}
if(frameCurrent > 0){
stateTransitionUtil.simulate(FallState.ACTIVE);
}
frameCurrent++;
} break;
case INACTIVE: {
if(this.shouldStart()){
this.start();
this.frameCurrent = 0;
}
frameCurrent++;
} break;
}
}
@ -98,6 +103,24 @@ public class ClientFallTree implements BehaviorTree {
return state == FallState.ACTIVE;
}
/**
* Checks if the fall tree should activate
* @return true if should activate, false otherwise
*/
protected boolean shouldStart(){
boolean isPlayingJump = false;
Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null && ClientJumpTree.getClientJumpTree(parent) != null){
isPlayingJump = entityActor.isPlayingAnimation(ClientJumpTree.getClientJumpTree(parent).getJumpData().getAnimationJump());
}
boolean rVal =
frameCurrent > ServerFallTree.MIN_FRAMES_BEFORE_ACTIVATION_SCAN &&
ClientGravityTree.getClientGravityTree(parent).isActive() &&
!isPlayingJump
;
return rVal;
}
/**
* Triggers the falling tree to land
*/
@ -105,23 +128,25 @@ public class ClientFallTree implements BehaviorTree {
if(state != FallState.INACTIVE){
state = FallState.INACTIVE;
this.stateTransitionUtil.interrupt(FallState.ACTIVE);
Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null){
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson())
){
entityActor.playAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER));
entityActor.incrementAnimationTime(0.0001);
if(frameCurrent > ServerFallTree.MIN_FRAMES_BEFORE_LANDING_ANIM){
Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null){
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson())
){
entityActor.playAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER));
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(parent, fallMovementSystem.getLandState().getAnimation());
}
if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson()){
//first person
Globals.movementAudioService.playAudioPositional(ClientVoxelSampler.getVoxelTypeBeneathEntity(parent), InteractionType.LAND, EntityUtils.getPosition(parent));
//play first person audio
} else {
//play third person audio
Globals.movementAudioService.playAudioPositional(ClientVoxelSampler.getVoxelTypeBeneathEntity(parent), InteractionType.LAND, EntityUtils.getPosition(parent));
}
FirstPersonTree.conditionallyPlayAnimation(parent, fallMovementSystem.getLandState().getAnimation());
}
if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson()){
//first person
Globals.movementAudioService.playAudioPositional(ClientVoxelSampler.getVoxelTypeBeneathEntity(parent), InteractionType.LAND, EntityUtils.getPosition(parent));
//play first person audio
} else {
//play third person audio
Globals.movementAudioService.playAudioPositional(ClientVoxelSampler.getVoxelTypeBeneathEntity(parent), InteractionType.LAND, EntityUtils.getPosition(parent));
}
frameCurrent = 0;
}

View File

@ -36,6 +36,16 @@ public class ServerFallTree implements BehaviorTree {
*/
int frameCurrent = 0;
/**
* The minimum frames to wait before scanning if it should activate due to gravity
*/
public static final int MIN_FRAMES_BEFORE_ACTIVATION_SCAN = 3;
/**
* The minimum frames to wait before playing landing animation on fall
*/
public static final int MIN_FRAMES_BEFORE_LANDING_ANIM = 3;
public ServerFallTree(Entity parent, FallMovementSystem fallMovementSystem){
this.parent = parent;
this.fallMovementSystem = fallMovementSystem;
@ -55,19 +65,25 @@ public class ServerFallTree implements BehaviorTree {
@Override
public void simulate(float deltaTime) {
switch(state){
case ACTIVE:
if(ServerGravityTree.getServerGravityTree(parent) != null && !ServerGravityTree.getServerGravityTree(parent).isActive()){
this.land();
break;
}
if(frameCurrent > 0){
stateTransitionUtil.simulate(FallState.ACTIVE);
}
frameCurrent++;
break;
case INACTIVE:
break;
case ACTIVE: {
if(ServerGravityTree.getServerGravityTree(parent) != null && !ServerGravityTree.getServerGravityTree(parent).isActive()){
this.land();
break;
}
if(frameCurrent > 0){
stateTransitionUtil.simulate(FallState.ACTIVE);
}
frameCurrent++;
} break;
case INACTIVE: {
if(this.shouldStart()){
this.start();
this.frameCurrent = 0;
}
frameCurrent++;
} break;
}
System.out.println(this.isFalling());
}
/**
@ -85,12 +101,34 @@ public class ServerFallTree implements BehaviorTree {
return state == FallState.ACTIVE;
}
/**
* Checks if the fall tree should activate
* @return true if should activate, false otherwise
*/
protected boolean shouldStart(){
boolean isPlayingJump = false;
PoseActor entityActor = EntityUtils.getPoseActor(parent);
if(entityActor != null && ServerJumpTree.getServerJumpTree(parent) != null){
isPlayingJump = entityActor.isPlayingAnimation(ServerJumpTree.getServerJumpTree(parent).getJumpData().getAnimationJump());
}
System.out.println(frameCurrent + " " + ServerGravityTree.getServerGravityTree(parent).isActive() + " " + !isPlayingJump);
boolean rVal =
frameCurrent > MIN_FRAMES_BEFORE_ACTIVATION_SCAN &&
ServerGravityTree.getServerGravityTree(parent).isActive() &&
!isPlayingJump
;
return rVal;
}
/**
* Triggers the falling tree to land
*/
public void land(){
if(state != FallState.INACTIVE){
state = FallState.INACTIVE;
this.stateTransitionUtil.interrupt(FallState.ACTIVE);
PoseActor poseActor = EntityUtils.getPoseActor(parent);
if(poseActor != null && frameCurrent > 3){
if(frameCurrent > MIN_FRAMES_BEFORE_LANDING_ANIM){
PoseActor poseActor = EntityUtils.getPoseActor(parent);
TreeDataAnimation animationToPlay = this.fallMovementSystem.getLandState().getAnimation();
if(
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)

View File

@ -147,6 +147,14 @@ public class ClientJumpTree implements BehaviorTree {
animationJump = animationName;
}
/**
* Gets the jump data for the tree
* @return The jump data
*/
public JumpMovementSystem getJumpData(){
return this.jumpData;
}
/**
* <p> Automatically generated </p>
* <p>

View File

@ -123,6 +123,14 @@ public class ServerJumpTree implements BehaviorTree {
return state == JumpState.ACTIVE;
}
/**
* Gets the jump data for the tree
* @return The jump data
*/
public JumpMovementSystem getJumpData(){
return this.jumpData;
}
public void setAnimationJump(String animationName){
animationJump = animationName;
}

View File

@ -39,7 +39,8 @@ public class ServerFallTreeTests extends EntityTestTemplate {
//make sure we're in in the air
TestEngineUtils.waitForCondition(() -> !serverJumpTree.isJumping(), 100);
assertEquals(true, serverFallTree.isFalling());
//Make sure we're eventually falling
assertEventually(() -> serverFallTree.isFalling());
}
@IntegrationTest