Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Public/AnimCustomInstance.h
mike zyracki 8441bf92a8 Add bWasCreated flag to BindToSkeletalMesh so when we know when we create the sequencer anim instance we should save the pose. This removes the need for control rig to override NativeInitialization. Also add some checks to make sure we save a valid pose.
#jira UE-76569

#rb max.chen

#ROBOMERGE-OWNER: ben.marsh
#ROBOMERGE-AUTHOR: mike.zyracki
#ROBOMERGE-SOURCE: CL 7280102 in //UE4/Release-4.23/... via CL 7280144
#ROBOMERGE-BOT: BUILD (Main -> Dev-Build) (v371-7306989)

[CL 7350675 by mike zyracki in Dev-Build branch]
2019-07-17 01:10:05 -04:00

73 lines
3.0 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
/**
*
* This Instance only contains one AnimationAsset, and produce poses
* Used by Preview in AnimGraph, Playing single animation in Kismet2 and etc
*/
#pragma once
#include "Animation/AnimInstance.h"
#include "Components/SkeletalMeshComponent.h"
#include "AnimCustomInstance.generated.h"
UCLASS(transient, NotBlueprintable)
class ANIMGRAPHRUNTIME_API UAnimCustomInstance : public UAnimInstance
{
GENERATED_UCLASS_BODY()
/**
* Called to bind a typed UAnimCustomInstance to an existing skeletal mesh component
* @return the current (or newly created) UAnimCustomInstance
*/
template<typename InstanceClassType>
static InstanceClassType* BindToSkeletalMeshComponent(USkeletalMeshComponent* InSkeletalMeshComponent, bool& bOutWasCreated)
{
bOutWasCreated = false;
// make sure to tick and refresh all the time when ticks
// @TODO: this needs restoring post-binding
InSkeletalMeshComponent->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::AlwaysTickPoseAndRefreshBones;
#if WITH_EDITOR
InSkeletalMeshComponent->SetUpdateAnimationInEditor(true);
#endif
// we use sequence instance if it's using anim blueprint that matches. Otherwise, we create sequence player
// this might need more check - i.e. making sure if it's same skeleton and so on,
// Ideally we could just call NeedToSpawnAnimScriptInstance call, which is protected now
const bool bShouldUseSequenceInstance = ShouldUseSequenceInstancePlayer(InSkeletalMeshComponent);
// if it should use sequence instance
if (bShouldUseSequenceInstance)
{
// this has to wrap around with this because we don't want to reinitialize everytime they come here
// SetAnimationMode will reinitiaize it even if it's same, so make sure we just call SetAnimationMode if not AnimationCustomMode
if (InSkeletalMeshComponent->GetAnimationMode() != EAnimationMode::AnimationCustomMode)
{
InSkeletalMeshComponent->SetAnimationMode(EAnimationMode::AnimationCustomMode);
}
if (Cast<UAnimCustomInstance>(InSkeletalMeshComponent->AnimScriptInstance) == nullptr || !InSkeletalMeshComponent->AnimScriptInstance->GetClass()->IsChildOf(InstanceClassType::StaticClass()))
{
InstanceClassType* SequencerInstance = NewObject<InstanceClassType>(InSkeletalMeshComponent, InstanceClassType::StaticClass());
InSkeletalMeshComponent->AnimScriptInstance = SequencerInstance;
InSkeletalMeshComponent->AnimScriptInstance->InitializeAnimation();
bOutWasCreated = true;
return SequencerInstance;
}
else
{
return Cast<InstanceClassType>(InSkeletalMeshComponent->AnimScriptInstance);
}
}
return nullptr;
}
/** Called to unbind a UAnimCustomInstance to an existing skeletal mesh component */
static void UnbindFromSkeletalMeshComponent(USkeletalMeshComponent* InSkeletalMeshComponent);
private:
/** Helper function for BindToSkeletalMeshComponent */
static bool ShouldUseSequenceInstancePlayer(const USkeletalMeshComponent* SkeletalMeshComponent);
};