bool SAnimCurveListRow::GetActiveWeight(float& OutWeight) const
{
	bool bFoundActive = false;

	// If anim viewer
	TSharedPtr<SAnimCurveViewer> AnimCurveViewer = AnimCurveViewerPtr.Pin();
	if (AnimCurveViewer.IsValid())
	{
		// If anim instance
		UAnimInstance* AnimInstance = PreviewScenePtr.Pin()->GetPreviewMeshComponent()->GetAnimInstance();
		if (AnimInstance)
		{
			// See if curve is in active set, attribute curve should have everything
			TMap<FName, float> CurveList;
			AnimInstance->GetAnimationCurveList(EAnimCurveType::AttributeCurve, CurveList);

			float* CurrentValue = CurveList.Find(Item->SmartName.DisplayName);
			if (CurrentValue)
			{
				OutWeight = *CurrentValue;
				// Remember we found it
				bFoundActive = true;
			}
		}
	}

	return bFoundActive;
}
예제 #2
0
void AMurphysLawCharacter::Fire()
{
	// check if we have a weapon equipped
	if (HasWeaponEquipped())
	{
		// if the weapon has been able to fire
		if (GetEquippedWeapon()->Fire(this))
		{
			// Stop the character from running
			SetIsRunning(false);

			// try and play a firing animation if specified
			if (FireAnimation != nullptr)
			{
				// Get the animation object for the arms mesh
				UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
				if (AnimInstance != nullptr)
				{
					AnimInstance->Montage_Play(FireAnimation, 1.f);
				}
			}

			// check for bullet collisions
			ComputeBulletCollisions();
		}

		// We reload the weapon if it is empty and we have bullets left in our inventory
		if (ShouldReload())
		{
			Reload();
		}
	}
}
void AMobileOpenCVCharacter::OnFire()
{ 
	// try and fire a projectile
	if (ProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			// spawn the projectile at the muzzle
			World->SpawnActor<AMobileOpenCVProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if(FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if(AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}

}
void FMovieSceneSkeletalAnimationTrackInstance::PreviewSetAnimPosition(USkeletalMeshComponent* SkeletalMeshComponent, FName SlotName, int32 ChannelIndex, UAnimSequenceBase* InAnimSequence, float InPosition, bool bLooping, bool bFireNotifies, float DeltaTime, bool bPlaying, bool bResetDynamics)
{
	if(CanPlayAnimation(SkeletalMeshComponent, InAnimSequence))
	{
		UAnimMontage* Montage = FAnimMontageInstance::PreviewMatineeSetAnimPositionInner(SlotName, SkeletalMeshComponent, InAnimSequence, InPosition, bLooping, bFireNotifies, DeltaTime);

		// if we are not playing, make sure we dont continue (as skeletal meshes can still tick us onwards)
		UAnimInstance* AnimInst = SkeletalMeshComponent->GetAnimInstance();
		UAnimSingleNodeInstance * SingleNodeInst = SkeletalMeshComponent->GetSingleNodeInstance();
		if(SingleNodeInst)
		{
			SingleNodeInst->SetPlaying(bPlaying);
		}
		else if (AnimInst)
		{
			if(Montage)
			{
				if(bPlaying)
				{
					AnimInst->Montage_Resume(Montage);
				}
				else
				{
					AnimInst->Montage_Pause(Montage);
				}
			}

			if(bResetDynamics)
			{
				// make sure we reset any simulations
				AnimInst->ResetDynamics();
			}
		}
	}
}
예제 #5
0
class UAnimMontage * ACharacter::GetCurrentMontage()
{
    UAnimInstance * AnimInstance = (Mesh)? Mesh->GetAnimInstance() : NULL;
    if ( AnimInstance )
    {
        return AnimInstance->GetCurrentActiveMontage();
    }

    return NULL;
}
예제 #6
0
void ACharacter::StopAnimMontage(class UAnimMontage* AnimMontage)
{
    UAnimInstance * AnimInstance = (Mesh)? Mesh->GetAnimInstance() : NULL;
    UAnimMontage * MontageToStop = (AnimMontage)? AnimMontage : GetCurrentMontage();
    bool bShouldStopMontage =  AnimInstance && MontageToStop && !AnimInstance->Montage_GetIsStopped(MontageToStop);

    if ( bShouldStopMontage )
    {
        AnimInstance->Montage_Stop(MontageToStop->BlendOutTime, MontageToStop);
    }
}
void AFP_FirstPersonCharacter::OnFire()
{
	// Play a sound if there is one
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if(FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if(AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}

	// Now send a trace from the end of our gun to see if we should hit anything
	APlayerController* PlayerController = Cast<APlayerController>(GetController());
	
	// Calculate the direction of fire and the start location for trace
	FVector CamLoc;
	FRotator CamRot;
	PlayerController->GetPlayerViewPoint(CamLoc, CamRot);
	const FVector ShootDir = CamRot.Vector();

	FVector StartTrace = FVector::ZeroVector;
	if (PlayerController)
	{
		FRotator UnusedRot;
		PlayerController->GetPlayerViewPoint(StartTrace, UnusedRot);

		// Adjust trace so there is nothing blocking the ray between the camera and the pawn, and calculate distance from adjusted start
		StartTrace = StartTrace + ShootDir * ((GetActorLocation() - StartTrace) | ShootDir);
	}

	// Calculate endpoint of trace
	const FVector EndTrace = StartTrace + ShootDir * WeaponRange;

	// Check for impact
	const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);

	// Deal with impact
	AActor* DamagedActor = Impact.GetActor();
	UPrimitiveComponent* DamagedComponent = Impact.GetComponent();

	// If we hit an actor, with a component that is simulating physics, apply an impulse
	if ((DamagedActor != NULL) && (DamagedActor != this) && (DamagedComponent != NULL) && DamagedComponent->IsSimulatingPhysics())
	{
		DamagedComponent->AddImpulseAtLocation(ShootDir*WeaponDamage, Impact.Location);
	}
}
bool FAnimBlueprintThumbnailScene::SetAnimBlueprint(class UAnimBlueprint* InBlueprint)
{
    PreviewActor->GetSkeletalMeshComponent()->OverrideMaterials.Empty();

    bool bSetSucessfully = false;

    PreviewBlueprint = InBlueprint;

    if (InBlueprint)
    {
        if (USkeleton* Skeleton = InBlueprint->TargetSkeleton)
        {
            USkeletalMesh* PreviewSkeletalMesh = Skeleton->GetPreviewMesh(true);

            PreviewActor->GetSkeletalMeshComponent()->SetSkeletalMesh(PreviewSkeletalMesh);

            if (PreviewSkeletalMesh)
            {
                bSetSucessfully = true;

                UAnimInstance* PreviousInstance = PreviewActor->GetSkeletalMeshComponent()->GetAnimInstance();

                PreviewActor->GetSkeletalMeshComponent()->SetAnimInstanceClass(InBlueprint->GeneratedClass);

                if (PreviousInstance && PreviousInstance != PreviewActor->GetSkeletalMeshComponent()->GetAnimInstance())
                {
                    //Mark this as gone!
                    PreviousInstance->MarkPendingKill();
                }

                FTransform MeshTransform = FTransform::Identity;

                PreviewActor->SetActorLocation(FVector(0, 0, 0), false);
                PreviewActor->GetSkeletalMeshComponent()->UpdateBounds();

                // Center the mesh at the world origin then offset to put it on top of the plane
                const float BoundsZOffset = GetBoundsZOffset(PreviewActor->GetSkeletalMeshComponent()->Bounds);
                PreviewActor->SetActorLocation(-PreviewActor->GetSkeletalMeshComponent()->Bounds.Origin + FVector(0, 0, BoundsZOffset), false);
                PreviewActor->GetSkeletalMeshComponent()->RecreateRenderState_Concurrent();
            }
        }
    }

    if (!bSetSucessfully)
    {
        CleanupComponentChildren(PreviewActor->GetSkeletalMeshComponent());
        PreviewActor->GetSkeletalMeshComponent()->SetSkeletalMesh(nullptr);
        PreviewActor->GetSkeletalMeshComponent()->SetAnimInstanceClass(nullptr);
    }

    return bSetSucessfully;
}
void AShaderPluginDemoCharacter::OnFire()
{
	//Try to set a texture to the object we hit!
	FHitResult HitResult;
	FVector StartLocation = FirstPersonCameraComponent->GetComponentLocation();
	FRotator Direction = FirstPersonCameraComponent->GetComponentRotation();
	FVector EndLocation = StartLocation + Direction.Vector() * 10000;
	FCollisionQueryParams QueryParams;
	QueryParams.AddIgnoredActor(this);

	if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility, QueryParams))
	{
		TArray<UStaticMeshComponent*> StaticMeshComponents = TArray<UStaticMeshComponent*>();
		AActor* HitActor = HitResult.GetActor();

		if (NULL != HitActor)
		{
			HitActor->GetComponents<UStaticMeshComponent>(StaticMeshComponents);
			for (int32 i = 0; i < StaticMeshComponents.Num(); i++)
			{
				UStaticMeshComponent* CurrentStaticMeshPtr = StaticMeshComponents[i];
				CurrentStaticMeshPtr->SetMaterial(0, MaterialToApplyToClickedObject);
				UMaterialInstanceDynamic* MID = CurrentStaticMeshPtr->CreateAndSetMaterialInstanceDynamic(0);
				UTexture* CastedRenderTarget = Cast<UTexture>(RenderTarget);
				MID->SetTextureParameterValue("InputTexture", CastedRenderTarget);
			}
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if (FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if (AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}
}
예제 #10
0
void AGWWeaponRanged::OnRep_ReloadBeign()
{
	OnReloadBegin();
	if (ReloadAnimation)
	{
		IIGISkeletalMesh* skelMeshInt = Cast<IIGISkeletalMesh>(Instigator);
		if (!skelMeshInt)
			return;

		UAnimInstance* AnimInst = skelMeshInt->GetMasterSkeletalMesh()->GetAnimInstance();
		if (!AnimInst)
			return;
		float montageLenght = ReloadAnimation->CalculateSequenceLength();

		float multiplier = montageLenght / ReloadTime;

		AnimInst->Montage_Play(ReloadAnimation, multiplier);
	}
}
void FMovieSceneSkeletalAnimationTrackInstance::FinishAnimControl(USkeletalMeshComponent* SkeletalMeshComponent)
{
	if(SkeletalMeshComponent->GetAnimationMode() == EAnimationMode::Type::AnimationBlueprint)
	{
		UAnimInstance* AnimInstance = SkeletalMeshComponent->GetAnimInstance();
		if(AnimInstance)
		{
			AnimInstance->Montage_Stop(0.f);
			AnimInstance->UpdateAnimation(0.f, false);
		}

		// Update space bases to reset it back to ref pose
		SkeletalMeshComponent->RefreshBoneTransforms();
		SkeletalMeshComponent->RefreshSlaveComponents();
		SkeletalMeshComponent->UpdateComponentToWorld();
	}

	CurrentlyPlayingMontage = nullptr;
}
void FMovieSceneSkeletalAnimationTrackInstance::SetAnimPosition(USkeletalMeshComponent* SkeletalMeshComponent, FName SlotName, int32 ChannelIndex, UAnimSequenceBase* InAnimSequence, float InPosition, bool bLooping, bool bFireNotifies)
{
	if (CanPlayAnimation(SkeletalMeshComponent, InAnimSequence))
	{
		UAnimMontage* Montage = FAnimMontageInstance::SetMatineeAnimPositionInner(SlotName, SkeletalMeshComponent, InAnimSequence, InPosition, bLooping);

		// Ensure the sequence is not stopped
		UAnimInstance* AnimInst = SkeletalMeshComponent->GetAnimInstance();
		UAnimSingleNodeInstance* SingleNodeInst = SkeletalMeshComponent->GetSingleNodeInstance();
		if(SingleNodeInst)
		{
			SingleNodeInst->SetPlaying(true);
		}
		else if (AnimInst && Montage)
		{
			AnimInst->Montage_Resume(Montage);
		}
	}
}
예제 #13
0
void ATotemCharacter::OnFire()
{
	//only server can spawn projectile theoretically
	// try and fire a projectile
	if (ProjectileClass != NULL || FireProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			//to add owner and instigator information
			FActorSpawnParameters SpawnParams;
			SpawnParams.Owner = Cast<ATotemPlayerController>(Controller);
			SpawnParams.Instigator = Instigator;
			//When the server function is called by serve, it also execute. 
			ServerSpawnProjectile(SpawnLocation, SpawnRotation, SpawnParams.Owner, SpawnParams.Instigator);
			// spawn the projectile at the muzzle single player version
			//World->SpawnActor<ATotemProjectile>(ProjectileClass, SpawnLocation, SpawnRotation, SpawnParams);
		}
	}


	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if (FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if (AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}

}
void AUDKPresentationCharacter::OnFire()
{ 
	if (CharacterMovement->IsMovingOnGround()) {
		ammo = maxAmmo;
	}
	if (ammo <= 0) return;
	// try and fire a projectile
	if (ProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		ammo--;
		CharacterMovement->Velocity = GetControlRotation().Vector()*(-1000) + 0.5f * CharacterMovement->Velocity;

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			// spawn the projectile at the muzzle
			World->SpawnActor<AUDKPresentationProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if(FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if(AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}

}
void UBTTask_ShowPhrases::TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
	Super::TickTask(OwnerComp, NodeMemory, DeltaSeconds);
	bool bCharacterAnimationFinished = true;

	if (DialogueCharacterAnimationOptions.bPlayAnimation)
	{
		CharacterAnimationDuration -= DeltaSeconds;
		if (CharacterAnimationDuration <=0.0f && DialogueCharacterAnimationOptions.bLoop && !bTextFinished)
		{
			UAnimInstance *AnimInst = Mesh->GetAnimInstance();
			if (AnimInst)
			{
				AnimInst->PlaySlotAnimationAsDynamicMontage(DialogueCharacterAnimationOptions.Animation,
					DialogueCharacterAnimationOptions.AnimationBlendOptions.SlotNodeName,
					DialogueCharacterAnimationOptions.AnimationBlendOptions.BlendInTime,
					DialogueCharacterAnimationOptions.AnimationBlendOptions.BlendOutTime,
					DialogueCharacterAnimationOptions.AnimationBlendOptions.InPlayRate);
			}
			UAnimSequenceBase* SequenceBase = DialogueCharacterAnimationOptions.Animation;
			CharacterAnimationDuration = SequenceBase->SequenceLength / SequenceBase->RateScale;
		}
		bCharacterAnimationFinished = (CharacterAnimationDuration <= 0.0f && bCharacterAnimationStarted) || (!DialogueCharacterAnimationOptions.bWaitEndOfAnimation && bTextFinished) ? true : false;
	}
	if (bTextFinished && bCharacterAnimationFinished)
	{
		bCharacterAnimationFinished = false;
		bTextFinished = false;
		ShowingNumPhrase = 0;
		UWidgetTree* WidgetTree = Widget->WidgetTree;
		UWidget* DialogueEventListener = WidgetTree->FindWidget(FName("DialogueEventListener"));
		if (DialogueEventListener != nullptr)
		{
			UDialogueEventListener* EventListener = Cast<UDialogueEventListener>(DialogueEventListener);
			if (EventListener)
			{
				EventListener->ShowPhrasesNode = nullptr;
			}
		}
		FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded);
	}
}
예제 #16
0
void AGun::OnEquip()
{
	Super::OnEquip();

	if (WeaponEquipAnimation)
	{
		Mesh->GetAnimInstance()->Montage_Play(WeaponEquipAnimation, 1.f);
	}

	if (PlayerEquipAnimation)
	{
		UAnimInstance* AnimInstance = Cast<AFPSCodeCharacter>(UGameplayStatics::GetPlayerCharacter(this, 0))->GetMesh1P()->GetAnimInstance();

		if (AnimInstance)
		{
			AnimInstance->Montage_Play(PlayerEquipAnimation, 1.f);
		}
	}

}
예제 #17
0
void AGun::Reload()
{
	if (!IsReloading)
	{
		if (CurrentAmmo < MagSize && TotalAmmo > 0)
		{
			IsReloading = true;

			//Playing Reload animation on weapon
			if (WeaponReloadAnimation)
			{
				Mesh->GetAnimInstance()->Montage_Play(WeaponReloadAnimation, 1.f);
			}

			//Playing Reload animation montage on player
			if (PlayerReloadAnimation)
			{
				UAnimInstance* AnimInstance = Cast<AFPSCodeCharacter>(UGameplayStatics::GetPlayerCharacter(this, 0))->GetMesh1P()->GetAnimInstance();

				if (AnimInstance)
				{
					bCanAttack = false;

					float AnimTime = AnimInstance->Montage_Play(PlayerReloadAnimation, 1.f);

					FTimerHandle AnimHandle;
                      
					GetWorld()->GetTimerManager().SetTimer(AnimHandle, this, &AGun::SetAmmoValues, AnimTime);      //Set timer to apply reloaded ammo values when animation is done
				}
				else
				{
					SetAmmoValues();
				}
			}
			else
			{
				SetAmmoValues();
			}
		}
	}
}
예제 #18
0
float ACharacter::PlayAnimMontage(class UAnimMontage* AnimMontage, float InPlayRate, FName StartSectionName)
{
    UAnimInstance * AnimInstance = (Mesh)? Mesh->GetAnimInstance() : NULL;
    if( AnimMontage && AnimInstance )
    {
        float const Duration = AnimInstance->Montage_Play(AnimMontage, InPlayRate);

        if (Duration > 0.f)
        {
            // Start at a given Section.
            if( StartSectionName != NAME_None )
            {
                AnimInstance->Montage_JumpToSection(StartSectionName, AnimMontage);
            }

            return Duration;
        }
    }

    return 0.f;
}
예제 #19
0
void ABETCharacter::OnFire()
{ 
	if (Weapon){
		Weapon->Fire();
	}

	// try and play the sound if specified
	if (Weapon->FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, Weapon->FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if (Weapon->FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if (AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(Weapon->FireAnimation, 1.f);
		}
	}
}
void FMovieSceneSkeletalAnimationTrackInstance::PreviewFinishAnimControl(USkeletalMeshComponent* SkeletalMeshComponent)
{
	if (CanPlayAnimation(SkeletalMeshComponent))
	{
		// if in editor, reset the Animations, makes easier for artist to see them visually and align them
		// in game, we keep the last pose that matinee kept. If you'd like it to have animation, you'll need to have AnimTree or AnimGraph to handle correctly
		if (SkeletalMeshComponent->GetAnimationMode() == EAnimationMode::Type::AnimationBlueprint)
		{
			UAnimInstance* AnimInstance = SkeletalMeshComponent->GetAnimInstance();
			if(AnimInstance)
			{
				AnimInstance->Montage_Stop(0.f);
				AnimInstance->UpdateAnimation(0.f, false);
			}
		}
		// Update space bases to reset it back to ref pose
		SkeletalMeshComponent->RefreshBoneTransforms();
		SkeletalMeshComponent->RefreshSlaveComponents();
		SkeletalMeshComponent->UpdateComponentToWorld();
	}

	CurrentlyPlayingMontage = nullptr;
}
void FAnimNode_QueuedSequencePlayer::Update(const FAnimationUpdateContext& Context)
{
	EvaluateGraphExposedInputs.Execute(Context);

	if (CurrentSequence == nullptr ||
	   (NextSequence != nullptr && (InternalTimeAccumulator + SMALL_NUMBER >= CurrentSequence->SequenceLength || LastInternalTimeAccumulator > InternalTimeAccumulator)))
	{
		CurrentSequence = NextSequence;
		InternalTimeAccumulator = 0;
	}

	if ((CurrentSequence != NULL) && (Context.AnimInstanceProxy->GetSkeleton()->IsCompatible(CurrentSequence->GetSkeleton())))
	{
		const float fTriggerTime = FMath::Max(0.f, CurrentSequence->SequenceLength - EndOfPlayEventTime);
		if (LastInternalTimeAccumulator < fTriggerTime && InternalTimeAccumulator >= fTriggerTime)
		{
			UAnimInstance* Instance = Context.AnimInstanceProxy->GetSkelMeshComponent()->GetAnimInstance();
			UFunction* EOPFunc = Instance->FindFunction(EndOfPlayEvent);
			if (EOPFunc != nullptr)
			{
				Instance->ProcessEvent(EOPFunc, nullptr);
			}
		}

		const float FinalBlendWeight = Context.GetFinalBlendWeight();

		// Create a tick record and fill it out
		UAnimInstance* Instance = Context.AnimInstanceProxy->GetSkelMeshComponent()->GetAnimInstance();
		FAnimGroupInstance* SyncGroup;
		FAnimTickRecord& TickRecord = Context.AnimInstanceProxy->CreateUninitializedTickRecord(INDEX_NONE, /*out*/ SyncGroup);

		Context.AnimInstanceProxy->MakeSequenceTickRecord(TickRecord, CurrentSequence, false, 1.0, FinalBlendWeight, /*inout*/ InternalTimeAccumulator, *TickRecord.MarkerTickRecord);
	}

	LastInternalTimeAccumulator = InternalTimeAccumulator;
}
예제 #22
0
void AWizardsCharacter::OnFire()
{
	if (!mySpellBook.IsValidIndex(0)) {
		UE_LOG(LogTemp, Warning, TEXT("Spell Gathering Needed!"));
		newCharactersSpells();
	}
	if (Mana > mySpellBook[currSpell].spellCost) {
		Mana -= mySpellBook[currSpell].spellCost;
		// try and fire a projectile

		if (mySpellBook[currSpell].spellType == 0)
		{
			const FRotator SpawnRotation = GetControlRotation();
			const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* projParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + 5];
				AWizardsProjectile* wizardsSpell = World->SpawnActor<AWizardsProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(&mySpellBook[currSpell], projParticle, blastParticle, this);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);//mySpellBook[currSpell]);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 1) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsBlast* wizardsSpell = World->SpawnActor<AWizardsBlast>(BlastClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(blastParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsSpell->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 2) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* coneParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsCone* wizardsCone = World->SpawnActor<AWizardsCone>(ConeClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsCone->SpellCreation(coneParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsCone->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks
				activeAttack = Cast<AActor>(wizardsCone);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		// God this sound is so annoying
		/*if (FireSound != NULL)
		{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
		}*/

		// try and play a firing animation if specified
		if (FireAnimation != NULL)
		{
			// Get the animation object for the arms mesh
			UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
			if (AnimInstance != NULL)
			{
				AnimInstance->Montage_Play(FireAnimation, 1.f);
			}
		}

	}
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void FAnimTransitionNodeDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder )
{
	// Get a handle to the node we're viewing
	const TArray< TWeakObjectPtr<UObject> >& SelectedObjects = DetailBuilder.GetDetailsView().GetSelectedObjects();
	for (int32 ObjectIndex = 0; !TransitionNode.IsValid() && (ObjectIndex < SelectedObjects.Num()); ++ObjectIndex)
	{
		const TWeakObjectPtr<UObject>& CurrentObject = SelectedObjects[ObjectIndex];
		if (CurrentObject.IsValid())
		{
			TransitionNode = Cast<UAnimStateTransitionNode>(CurrentObject.Get());
		}
	}

	bool bTransitionToConduit = false;
	if (UAnimStateTransitionNode* TransitionNodePtr = TransitionNode.Get())
	{
		UAnimStateNodeBase* NextState = TransitionNodePtr->GetNextState();
		bTransitionToConduit = (NextState != NULL) && (NextState->IsA<UAnimStateConduitNode>());
	}

	//////////////////////////////////////////////////////////////////////////

	IDetailCategoryBuilder& TransitionCategory = DetailBuilder.EditCategory("Transition", LOCTEXT("TransitionCategoryTitle", "Transition") );

	if (bTransitionToConduit)
	{
		// Transitions to conduits are just shorthand for some other real transition;
		// All of the blend related settings are ignored, so hide them.
		DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, Bidirectional));
		DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, CrossfadeDuration));
		DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, BlendMode));
		DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, LogicType));
		DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, PriorityOrder));
	}
	else
	{
		TransitionCategory.AddCustomRow( LOCTEXT("TransitionEventPropertiesCategoryLabel", "Transition") )
		[
			SNew( STextBlock )
			.Text( LOCTEXT("TransitionEventPropertiesCategoryLabel", "Transition") )
			.Font( IDetailLayoutBuilder::GetDetailFontBold() )
		];

		TransitionCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, PriorityOrder)).DisplayName(LOCTEXT("PriorityOrderLabel", "Priority Order"));
		TransitionCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, Bidirectional)).DisplayName(LOCTEXT("BidirectionalLabel", "Bidirectional"));
		TransitionCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, LogicType)).DisplayName(LOCTEXT("BlendLogicLabel", "Blend Logic") );

		UAnimStateTransitionNode* TransNode = TransitionNode.Get();
		if (TransitionNode != NULL)
		{
			// The sharing option for the rule
			TransitionCategory.AddCustomRow( LOCTEXT("TransitionRuleSharingLabel", "Transition Rule Sharing") )
			[
				GetWidgetForInlineShareMenu(TEXT("Transition Rule Sharing"), TransNode->SharedRulesName, TransNode->bSharedRules,
					FOnClicked::CreateSP(this, &FAnimTransitionNodeDetails::OnPromoteToSharedClick, true),
					FOnClicked::CreateSP(this, &FAnimTransitionNodeDetails::OnUnshareClick, true), 
					FOnGetContent::CreateSP(this, &FAnimTransitionNodeDetails::OnGetShareableNodesMenu, true))
			];


// 			TransitionCategory.AddRow()
// 				[
// 					SNew( STextBlock )
// 					.Text( TEXT("Crossfade Settings") )
// 					.Font( IDetailLayoutBuilder::GetDetailFontBold() )
// 				];


			// Show the rule itself
			UEdGraphPin* CanExecPin = NULL;
			if (UAnimationTransitionGraph* TransGraph = Cast<UAnimationTransitionGraph>(TransNode->BoundGraph))
			{
				if (UAnimGraphNode_TransitionResult* ResultNode = TransGraph->GetResultNode())
				{
					CanExecPin = ResultNode->FindPin(TEXT("bCanEnterTransition"));
				}
			}

			// indicate if a native transition rule applies to this
			UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForNodeChecked(TransitionNode.Get());
			if(Blueprint && Blueprint->ParentClass)
			{
				UAnimInstance* AnimInstance = CastChecked<UAnimInstance>(Blueprint->ParentClass->GetDefaultObject());
				if(AnimInstance)
				{
					UEdGraph* ParentGraph = TransitionNode->GetGraph();
					UAnimStateNodeBase* PrevState = TransitionNode->GetPreviousState();
					UAnimStateNodeBase* NextState = TransitionNode->GetNextState();
					if(PrevState != nullptr && NextState != nullptr && ParentGraph != nullptr)
					{
						FName FunctionName;
						if(AnimInstance->HasNativeTransitionBinding(ParentGraph->GetFName(), FName(*PrevState->GetStateName()), FName(*NextState->GetStateName()), FunctionName))
						{
							TransitionCategory.AddCustomRow( LOCTEXT("NativeBindingPresent_Filter", "Transition has native binding") )
							[
								SNew(STextBlock)
								.Text(FText::Format(LOCTEXT("NativeBindingPresent", "Transition has native binding to {0}()"), FText::FromName(FunctionName)))
								.Font( IDetailLayoutBuilder::GetDetailFontBold() )
							];
						}
					}
				}
			}

			TransitionCategory.AddCustomRow( CanExecPin ? CanExecPin->PinFriendlyName : FText::GetEmpty() )
			[
				SNew(SKismetLinearExpression, CanExecPin)
			];
		}

		//////////////////////////////////////////////////////////////////////////

		IDetailCategoryBuilder& CrossfadeCategory = DetailBuilder.EditCategory("BlendSettings", LOCTEXT("BlendSettingsCategoryTitle", "BlendSettings") );
		if (TransitionNode != NULL)
		{
			// The sharing option for the crossfade settings
			CrossfadeCategory.AddCustomRow( LOCTEXT("TransitionCrossfadeSharingLabel", "Transition Crossfade Sharing") )
			[
				GetWidgetForInlineShareMenu(TEXT("Transition Crossfade Sharing"), TransNode->SharedCrossfadeName, TransNode->bSharedCrossfade,
					FOnClicked::CreateSP(this, &FAnimTransitionNodeDetails::OnPromoteToSharedClick, false), 
					FOnClicked::CreateSP(this, &FAnimTransitionNodeDetails::OnUnshareClick, false), 
					FOnGetContent::CreateSP(this, &FAnimTransitionNodeDetails::OnGetShareableNodesMenu, false))
			];
		}

		//@TODO: Gate editing these on shared non-authorative ones
		CrossfadeCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, CrossfadeDuration)).DisplayName( LOCTEXT("DurationLabel", "Duration") );
		CrossfadeCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, BlendMode)).DisplayName( LOCTEXT("ModeLabel", "Mode") );
		CrossfadeCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, CustomBlendCurve)).DisplayName(LOCTEXT("CurveLabel", "Custom Blend Curve"));

		USkeleton* TargetSkeleton = TransitionNode->GetAnimBlueprint()->TargetSkeleton;

		if(TargetSkeleton)
		{
			TSharedPtr<IPropertyHandle> BlendProfileHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, BlendProfile));
			UObject* BlendProfilePropertyValue = nullptr;
			BlendProfileHandle->GetValue(BlendProfilePropertyValue);
			UBlendProfile* CurrentProfile = Cast<UBlendProfile>(BlendProfilePropertyValue);

			ISkeletonEditorModule& SkeletonEditorModule = FModuleManager::LoadModuleChecked<ISkeletonEditorModule>("SkeletonEditor");

			FBlendProfilePickerArgs Args;
			Args.InitialProfile = CurrentProfile;
			Args.OnBlendProfileSelected = FOnBlendProfileSelected::CreateSP(this, &FAnimTransitionNodeDetails::OnBlendProfileChanged, BlendProfileHandle);
			Args.bAllowNew = false;

			CrossfadeCategory.AddProperty(BlendProfileHandle).CustomWidget(true)
				.NameContent()
				[
					BlendProfileHandle->CreatePropertyNameWidget()
				]
				.ValueContent()
				[
					SkeletonEditorModule.CreateBlendProfilePicker(TargetSkeleton, Args)
				];
		}

		// Add a button that is only visible when blend logic type is custom
		CrossfadeCategory.AddCustomRow( LOCTEXT("EditBlendGraph", "Edit Blend Graph") )
		[
			SNew( SHorizontalBox )
			+SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.FillWidth(1)
			.Padding(0,0,10.0f,0)
			[
				SNew(SButton)
				.HAlign(HAlign_Right)
				.OnClicked(this, &FAnimTransitionNodeDetails::OnClickEditBlendGraph)
				.Visibility( this, &FAnimTransitionNodeDetails::GetBlendGraphButtonVisibility )
				.Text(LOCTEXT("EditBlendGraph", "Edit Blend Graph"))
			]
		];

		//////////////////////////////////////////////////////////////////////////

		IDetailCategoryBuilder& NotificationCategory = DetailBuilder.EditCategory("Notifications", LOCTEXT("NotificationsCategoryTitle", "Notifications") );

		NotificationCategory.AddCustomRow( LOCTEXT("StartTransitionEventPropertiesCategoryLabel", "Start Transition Event") )
		[
			SNew( STextBlock )
			.Text( LOCTEXT("StartTransitionEventPropertiesCategoryLabel", "Start Transition Event") )
			.Font( IDetailLayoutBuilder::GetDetailFontBold() )
		];
		CreateTransitionEventPropertyWidgets(NotificationCategory, TEXT("TransitionStart"));


		NotificationCategory.AddCustomRow( LOCTEXT("EndTransitionEventPropertiesCategoryLabel", "End Transition Event" ) ) 
		[
			SNew( STextBlock )
			.Text( LOCTEXT("EndTransitionEventPropertiesCategoryLabel", "End Transition Event" ) )
			.Font( IDetailLayoutBuilder::GetDetailFontBold() )
		];
		CreateTransitionEventPropertyWidgets(NotificationCategory, TEXT("TransitionEnd"));

		NotificationCategory.AddCustomRow( LOCTEXT("InterruptTransitionEventPropertiesCategoryLabel", "Interrupt Transition Event") )
		[
			SNew( STextBlock )
			.Text( LOCTEXT("InterruptTransitionEventPropertiesCategoryLabel", "Interrupt Transition Event") )
			.Font( IDetailLayoutBuilder::GetDetailFontBold() )
		];
		CreateTransitionEventPropertyWidgets(NotificationCategory, TEXT("TransitionInterrupt"));
	}

	DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, TransitionStart));
	DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UAnimStateTransitionNode, TransitionEnd));
}
EBTNodeResult::Type UBTTask_ShowPhrases::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{	
	EBTNodeResult::Type NodeResult = ShowingNumPhrase <= PhrasesCount ? EBTNodeResult::InProgress : NodeResult = EBTNodeResult::Succeeded;
	// reset timer handle
	TimerHandle.Invalidate();
	//AudioComponent = NULL;
	
	if (!DialogueWidget.IsNone())
	{
		FName WidgetKeyName = DialogueWidget.SelectedKeyName;
		BlackboardComp = OwnerComp.GetBlackboardComponent();
		Widget = Cast<UUserWidget>(BlackboardComp->GetValueAsObject(WidgetKeyName));
		WidgetComp = Cast<UWidgetComponent>(BlackboardComp->GetValueAsObject(WidgetKeyName));
		OwnerActor = OwnerComp.GetOwner();

		if (!Widget && !WidgetComp)
		{
#if WITH_EDITOR
			FMessageLog("PIE").Error()
				->AddToken(FTextToken::Create(LOCTEXT("InvalidWidgetKey", "Invalid key for Dialogue Widget in ")))
				->AddToken(FUObjectToken::Create((UObject*)OwnerComp.GetCurrentTree()));
#endif
			return EBTNodeResult::Failed;
		}

		if (WidgetComp)
		{
			Widget = CreateWidget<UUserWidget>(GetWorld(), WidgetComp->GetWidgetClass());
			bIsUserWidget = false;
		}
		else
		{
			bIsUserWidget = true;
		}

		if (Widget && Widget->IsInViewport())
		{
			Widget->RemoveFromParent();
		}

		if (Widget && !Widget->IsInViewport())
		{
			UWidgetTree* WidgetTree = Widget->WidgetTree;
			UWidget* DialogueQuestionsSlot = WidgetTree->FindWidget(DialogueTextOptions.DialogueQuestionsSlotName);
			if (DialogueQuestionsSlot != nullptr)
			{
				DialogueQuestionsSlot->SetVisibility(ESlateVisibility::Hidden);
			}

			// text
			DialoguePhraseSlot = WidgetTree->FindWidget(DialogueTextOptions.DialoguePhraseSlotName);
			if (DialoguePhraseSlot != nullptr)
			{
				DialoguePhraseSlot->SetVisibility(ESlateVisibility::Visible);
				UTextBlock* StartPhraseTextBlock = Cast<UTextBlock>(DialoguePhraseSlot);
				if (StartPhraseTextBlock)
				{
					if (DialogueTextOptions.bShowTextPhrases)
					{
						PhrasesCount = DialogueTextOptions.Phrases.Num() - 1; // starts from 0
						if (ShowingNumPhrase > PhrasesCount)
						{
							ShowingNumPhrase = 0;
						}
						FText StartPhrase = DialogueTextOptions.Phrases.Num() > 0 ? DialogueTextOptions.Phrases[ShowingNumPhrase].Phrase : FText::GetEmpty();
						if (DialogueTextOptions.TextEffect == ETextEffect::NoEffect || DialogueTextOptions.Delay == 0.0f)
						{
							StartPhraseTextBlock->SetText(FText::Format(NSLOCTEXT("DialogueSystem", "ShowPhraseText", "{0}"), StartPhrase));
							float ShowingTime = DialogueTextOptions.UseGeneralTime ? DialogueTextOptions.GeneralShowingTime : DialogueTextOptions.Phrases[ShowingNumPhrase].ShowingTime;
							TimerDelegate = FTimerDelegate::CreateUObject(this, &UBTTask_ShowPhrases::ShowNewDialoguePhrase, false);
							OwnerActor->GetWorldTimerManager().SetTimer(TimerHandle, TimerDelegate, ShowingTime, false);
						}
						else
						{
							if (DialogueTextOptions.TextEffect == ETextEffect::Typewriter)
							{
								CurrentCharNum = 1; StringToDisplay = "";
								FullString = StartPhrase.ToString().GetCharArray();
								StringToDisplay.AppendChar(FullString[0]);
								if (StartPhraseTextBlock)
								{
									StartPhraseTextBlock->SetText(FText::Format(NSLOCTEXT("DialogueSystem", "ShowPhraseText", "{0}"), FText::FromString(StringToDisplay)));
								}
								TimerDelegate = FTimerDelegate::CreateUObject(this, &UBTTask_ShowPhrases::ShowNewChar);
								OwnerActor->GetWorldTimerManager().SetTimer(TimerHandle, TimerDelegate, DialogueTextOptions.Delay, false);
							}
						}
						// play phrase sound 
						if (DialogueTextOptions.Phrases[ShowingNumPhrase].SoundToPlay)
						{
							PhraseAudioComponent = UGameplayStatics::SpawnSound2D(GetWorld(), DialogueTextOptions.Phrases[ShowingNumPhrase].SoundToPlay);
						}
					}
					else
					{
						DialoguePhraseSlot->SetVisibility(ESlateVisibility::Hidden);
						bTextFinished = true;
					}
				}
			}
			// name
			DialogueNameSlot = WidgetTree->FindWidget(DialogueNameOptions.DialogueSpeakerNameSlotName);
			if (DialogueNameSlot != nullptr)
			{
				if (DialogueNameOptions.bShowName)
				{
					DialogueNameSlot->SetVisibility(ESlateVisibility::Visible);
					UTextBlock* NameTextBlock = Cast<UTextBlock>(DialogueNameSlot);
					if (NameTextBlock)
					{
						NameTextBlock->SetText(DialogueNameOptions.Name);
					}
				}
				else
				{
					DialogueNameSlot->SetVisibility(ESlateVisibility::Hidden);
				}
			}
			// image
			DialogueImageSlot = WidgetTree->FindWidget(DialogueImageOptions.DialogueSpeakerImageSlotName);
			if (DialogueImageSlot != nullptr)
			{
				if (DialogueImageOptions.bShowImage)
				{
					DialogueImageSlot->SetVisibility(ESlateVisibility::Visible);
					UImage* DialogueImage = Cast<UImage>(DialogueImageSlot);
					if (DialogueImage)
					{
						DialogueImage->SetBrushFromTexture(DialogueImageOptions.Image);
					}
				}
				else
				{
					DialogueImageSlot->SetVisibility(ESlateVisibility::Hidden);
				}
			}
			// general sound
			if (DialogueSoundOptions.bPlaySound)
			{
				if (DialogueSoundOptions.SoundToPlay)
				{
					GeneralAudioComponent = UGameplayStatics::SpawnSound2D(GetWorld(), DialogueSoundOptions.SoundToPlay);
				}
			}
			// camera
			if (DialogueCameraOptions.bUseCamera)
			{
				if (!DialogueCameraOptions.CameraToView.IsNone() && !DialogueCameraOptions.PlayerCamera.IsNone() && !DialogueCinematicOptions.bPlayMatinee)
				{
					FName CameraToViewKeyName = DialogueCameraOptions.CameraToView.SelectedKeyName;
					BlackboardComp = OwnerComp.GetBlackboardComponent();
					UCameraComponent* CameraToView = Cast<UCameraComponent>(BlackboardComp->GetValueAsObject(CameraToViewKeyName));

					FName PlayerCameraKeyName = DialogueCameraOptions.PlayerCamera.SelectedKeyName;
					PlayerCamera = Cast<UCameraComponent>(BlackboardComp->GetValueAsObject(PlayerCameraKeyName));

					if (PlayerCamera && CameraToView)
					{
						SaveDefaultCameraData(PlayerCamera);
						if (PlayerCamera == CameraToView)
						{
							PlayerCamera->SetWorldLocationAndRotation(DefaultCameraLocation, DefaultCameraRotation);
						}
						else
						{
							PlayerCamera->SetWorldLocationAndRotation(CameraToView->GetComponentLocation(), CameraToView->GetComponentRotation());
						}
					}
				}
				
			}
			// cinematic
			if (DialogueCinematicOptions.bPlayMatinee && !DialogueCinematicOptions.Matinee.Equals("None"))
			{
				for (TActorIterator<AMatineeActor> It(OwnerActor->GetWorld()); It; ++It)
				{
					MatineeActor = *It;
					if (MatineeActor && MatineeActor->GetName().Equals(DialogueCinematicOptions.Matinee))
					{
						MatineeActor->bLooping = DialogueCinematicOptions.bLoop;
						MatineeActor->Play();
						break;
					}
				}
			}

			// character animation
			if (DialogueCharacterAnimationOptions.bPlayAnimation && !DialogueCharacterAnimationOptions.Mesh.IsNone() && DialogueCharacterAnimationOptions.Animation != nullptr)
			{
				FName MeshKeyName = DialogueCharacterAnimationOptions.Mesh.SelectedKeyName;
				BlackboardComp = OwnerComp.GetBlackboardComponent();
				Mesh = Cast<USkeletalMeshComponent>(BlackboardComp->GetValueAsObject(MeshKeyName));
				if (Mesh)
				{
					UAnimInstance *AnimInst = Mesh->GetAnimInstance();
					if (AnimInst)
					{
						AnimInst->PlaySlotAnimationAsDynamicMontage(DialogueCharacterAnimationOptions.Animation, 
							DialogueCharacterAnimationOptions.AnimationBlendOptions.SlotNodeName,
							DialogueCharacterAnimationOptions.AnimationBlendOptions.BlendInTime,
							DialogueCharacterAnimationOptions.AnimationBlendOptions.BlendOutTime,
							DialogueCharacterAnimationOptions.AnimationBlendOptions.InPlayRate);
					}
					if (DialogueCharacterAnimationOptions.bWaitEndOfAnimation)
					{
						UAnimSequenceBase* SequenceBase = DialogueCharacterAnimationOptions.Animation;
						CharacterAnimationDuration = SequenceBase->SequenceLength / SequenceBase->RateScale;
					}
				}
				bCharacterAnimationStarted = true;
			}
			// Event Listener

			UWidget* DialogueEventListener = WidgetTree->FindWidget(FName("DialogueEventListener"));
			if (DialogueEventListener != nullptr)
			{
				UDialogueEventListener* EventListener = Cast<UDialogueEventListener>(DialogueEventListener);
				if (EventListener)
				{
					EventListener->ShowPhrasesNode = this;
				}
			}
	
			if (bIsUserWidget)
			{
				Widget->AddToViewport();
			}
			else
			{
				WidgetComp->SetWidget(Widget);
				WidgetComp->SetVisibility(true);
			}
			PlayerController = Widget->GetOwningPlayer();
			if (InputMode == EWidggetInputMode::UIOnly)
			{
				FInputModeUIOnly InputModeUIOnly;
				InputModeUIOnly.SetWidgetToFocus(Widget->TakeWidget());
				PlayerController->SetInputMode(InputModeUIOnly);
			}
			else
			{
				FInputModeGameAndUI InputModeGameAndUI;
				InputModeGameAndUI.SetWidgetToFocus(Widget->TakeWidget());
				PlayerController->SetInputMode(InputModeGameAndUI);
			}
		}
		else
		{
			bTextFinished = true;
			NodeResult = EBTNodeResult::Failed;
		}
	}
	
	return NodeResult;
}