コード例 #1
0
void UAnimSet::ClearAllAnimSetLinkupCaches()
{
	double Start = FPlatformTime::Seconds();

	TArray<UAnimSet*> AnimSets;
	TArray<USkeletalMeshComponent*> SkelComps;
	// Find all AnimSets and SkeletalMeshComponents (just do one iterator)
	for(TObjectIterator<UObject> It;It;++It)
	{
		UAnimSet* AnimSet = Cast<UAnimSet>(*It);
		if(AnimSet && !AnimSet->IsPendingKill() && !AnimSet->IsTemplate())
		{
			AnimSets.Add(AnimSet);
		}

		USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(*It);
		if(SkelComp && !SkelComp->IsPendingKill() && !SkelComp->IsTemplate())
		{
			SkelComps.Add(SkelComp);
		}
	}

	// For all AnimSets, empty their linkup cache
	for(int32 i=0; i<AnimSets.Num(); i++)
	{
		AnimSets[i]->LinkupCache.Empty();
		AnimSets[i]->SkelMesh2LinkupCache.Empty();
	}

	UE_LOG(LogAnimation, Log, TEXT("ClearAllAnimSetLinkupCaches - Took %3.2fms"), (FPlatformTime::Seconds() - Start)*1000.f);
}
コード例 #2
0
ACVehicleSpawner::ACVehicleSpawner(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer){
	USkeletalMeshComponent* Mesh = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("Mesh"));
	static ConstructorHelpers::FObjectFinder<USkeletalMesh> PlaceHolderMesh(TEXT("SkeletalMesh'/Game/Spawner/placeholder_vehicle.placeholder_vehicle'"));
	Mesh->SetSkeletalMesh(PlaceHolderMesh.Object);
	RootComponent = Mesh;

	SetActorHiddenInGame(true);

	static ConstructorHelpers::FClassFinder<AFlockingVehicle> CarFinder(TEXT("/Game/Vehicle/FlockingCar"));
	static ConstructorHelpers::FClassFinder<AFlockingVehicle> SedanFinder(TEXT("/Game/Vehicle/FlockingSedan"));
	static ConstructorHelpers::FClassFinder<AFlockingVehicle> EmergencyFinder(TEXT("/Game/Vehicle/EmergencyVehicle"));
	static ConstructorHelpers::FClassFinder<AFlockingVehicle> BusFinder(TEXT("/Game/Vehicle/FlockingBus"));
	static ConstructorHelpers::FObjectFinder<UMaterial> Yellow(TEXT("Material'/Game/Sedan/Materials/M_Vehicle_Sedan_yelllo.M_Vehicle_Sedan_yelllo'"));
	static ConstructorHelpers::FObjectFinder<UMaterial> Blue(TEXT("Material'/Game/Sedan/Materials/M_Vehicle_Sedan.M_Vehicle_Sedan'"));
	static ConstructorHelpers::FObjectFinder<UMaterial> Green(TEXT("Material'/Game/Sedan/Materials/M_Vehicle_Sedan_green.M_Vehicle_Sedan_green'"));


	VehicleTypeClass.Add((uint8)EVehicleType::VT_Car, CarFinder.Class);
	VehicleTypeClass.Add((uint8)EVehicleType::VT_Sedan, SedanFinder.Class);
	VehicleTypeClass.Add((uint8)EVehicleType::VT_Bus, BusFinder.Class);
	VehicleTypeClass.Add((uint8)EVehicleType::VT_Emergency, EmergencyFinder.Class);

	TArray<UMaterial*> Materials;
	Materials.Add(Yellow.Object);
	Materials.Add(Blue.Object);
	Materials.Add(Green.Object);

	VehicleTypeMaterials.Add((uint8)EVehicleType::VT_Car, Materials);
	VehicleTypeMaterials.Add((uint8)EVehicleType::VT_Sedan, Materials);
}
FBox UPhysicsConstraintComponent::GetBodyBoxInternal(EConstraintFrame::Type Frame, FName InBoneName) const
{
	FBox ResultBox(0);

	UPrimitiveComponent* PrimComp  = GetComponentInternal(Frame);

	// Skeletal case
	USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(PrimComp);
	if(SkelComp != NULL)
	{
		UPhysicsAsset * const PhysicsAsset = SkelComp->GetPhysicsAsset();
		if (PhysicsAsset)
		{
			int32 BoneIndex = SkelComp->GetBoneIndex(InBoneName);
			int32 BodyIndex = PhysicsAsset->FindBodyIndex(InBoneName);
			if(BoneIndex != INDEX_NONE && BodyIndex != INDEX_NONE)
			{	
				const FTransform BoneTransform = SkelComp->GetBoneTransform(BoneIndex);
				ResultBox = PhysicsAsset->BodySetup[BodyIndex]->AggGeom.CalcAABB(BoneTransform);
			}
		}
	}
	else if(PrimComp != NULL)
	{
		ResultBox = PrimComp->Bounds.GetBox();
	}

	return ResultBox;
}
コード例 #4
0
void UAnimSet::ResetAnimSet()
{
#if WITH_EDITORONLY_DATA
	// Make sure we handle AnimSequence references properly before emptying the array.
	for(int32 i=0; i<Sequences.Num(); i++)
	{	
		UAnimSequence* AnimSeq = Sequences[i];
		if( AnimSeq )
		{
			AnimSeq->RecycleAnimSequence();
		}
	}
	Sequences.Empty();
	TrackBoneNames.Empty();
	LinkupCache.Empty();
	SkelMesh2LinkupCache.Empty();

	// We need to re-init any skeleltal mesh components now, because they might still have references to linkups in this set.
	for(TObjectIterator<USkeletalMeshComponent> It;It;++It)
	{
		USkeletalMeshComponent* SkelComp = *It;
		if(!SkelComp->IsPendingKill() && !SkelComp->IsTemplate())
		{
			SkelComp->InitAnim(true);
		}
	}
#endif // WITH_EDITORONLY_DATA
}
void FMovieSceneSkeletalAnimationTrackInstance::RefreshInstance( const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance )
{
	UpdateRefreshBones(RuntimeObjects);

	// When not in preview playback we need to stop any running animations to prevent the animations from being advanced a frame when
	// they are ticked by the engine.
	for ( TWeakObjectPtr<UObject> RuntimeObjectPtr : RuntimeObjects )
	{
		if ( ShouldUsePreviewPlayback( Player, RuntimeObjectPtr.Get() ) == false )
		{
			USkeletalMeshComponent* SkeletalMeshComponent = GetSkeletalMeshComponentFromRuntimeObjectPtr( RuntimeObjectPtr );
			if ( SkeletalMeshComponent != nullptr )
			{
				UAnimInstance* AnimInstance = SkeletalMeshComponent->GetAnimInstance();
				if ( AnimInstance )
				{
					UAnimSingleNodeInstance * SingleNodeInstance = SkeletalMeshComponent->GetSingleNodeInstance();
					if ( SingleNodeInstance )
					{
						SingleNodeInstance->SetPlaying( false );
					}
					// TODO: Anim montage?
				}
			}
		}
	}
}
コード例 #6
0
void AShooterWeapon::AttachMeshToPawn()
{
	if (MyPawn)
	{
		// Remove and hide both first and third person meshes
		DetachMeshFromPawn();

		// For locally controller players we attach both weapons and let the bOnlyOwnerSee, bOwnerNoSee flags deal with visibility.
		FName AttachPoint = MyPawn->GetWeaponAttachPoint();
		if( MyPawn->IsLocallyControlled() == true )
		{
			USkeletalMeshComponent* PawnMesh1p = MyPawn->GetSpecifcPawnMesh(true);
			USkeletalMeshComponent* PawnMesh3p = MyPawn->GetSpecifcPawnMesh(false);
			Mesh1P->SetHiddenInGame( false );
			Mesh3P->SetHiddenInGame( false );
			Mesh1P->AttachTo(PawnMesh1p, AttachPoint);
			Mesh3P->AttachTo(PawnMesh3p, AttachPoint);
		}
		else
		{
			USkeletalMeshComponent* UseWeaponMesh = GetWeaponMesh();
			USkeletalMeshComponent* UsePawnMesh = MyPawn->GetPawnMesh();
			UseWeaponMesh->AttachTo(UsePawnMesh, AttachPoint);	
			UseWeaponMesh->SetHiddenInGame( false );
		}
	}
}
コード例 #7
0
void UAnimInstance::SetMorphTarget(FName MorphTargetName, float Value)
{
	USkeletalMeshComponent * Component = GetOwningComponent();
	if (Component)
	{
		Component->SetMorphTarget(MorphTargetName, Value);
	}
}
コード例 #8
0
void UAnimInstance::ClearMorphTargets()
{
	USkeletalMeshComponent * Component = GetOwningComponent();
	if (Component)
	{
		Component->ClearMorphTargets();
	}
}
コード例 #9
0
ファイル: ARCharacter.cpp プロジェクト: iniside/ActionRPGGame
FVector AARCharacter::GetMainWeaponSocket(const FName& Socket) const
{
	USkeletalMeshComponent* Component = GetMainWeaponMesh();
	if (!Component)
		return GetMesh()->GetSocketLocation(TEXT("headSocket"));

	return Component->GetSocketLocation(Socket);
}
コード例 #10
0
APawn* UAnimInstance::TryGetPawnOwner()
{
	USkeletalMeshComponent* OwnerComponent = GetSkelMeshComponent();
	if (AActor* OwnerActor = OwnerComponent->GetOwner())
	{
		return Cast<APawn>(OwnerActor);
	}

	return NULL;
}
コード例 #11
0
void ASFlashlight::BeginPlay()
{
	Super::BeginPlay();

	/* Create an instance unique to this actor instance to manipulate emissive intensity */
	USkeletalMeshComponent* MeshComp = GetWeaponMesh();
	if (MeshComp)
	{
		MatDynamic = MeshComp->CreateAndSetMaterialInstanceDynamic(0);
	}
}
コード例 #12
0
FWidget::EWidgetMode FFabrikEditMode::GetWidgetMode() const
{
	USkeletalMeshComponent* SkelComp = GetAnimPreviewScene().GetPreviewMeshComponent();
	int32 BoneIndex = SkelComp->GetBoneIndex(GraphNode->Node.EffectorTransformBone.BoneName);

	if (BoneIndex != INDEX_NONE)
	{
		return FWidget::WM_Translate;
	}

	return FWidget::WM_None;
}
コード例 #13
0
void AGamePlayCharacter::OnDeath(float KillingDamage, FDamageEvent const& DamageEvent, APawn* PawnInstigator, AActor* DamageCauser)
{
	Super::OnDeath(KillingDamage, DamageEvent, PawnInstigator, DamageCauser);
	if (CurrentWeapon)
	{
		CurrentWeapon->GetRootComponent()->DetachFromParent();
		USkeletalMeshComponent* WeaponMesh = CurrentWeapon->WeaponMesh;
		if (WeaponMesh)
		{
			WeaponMesh->SetSimulatePhysics(true);
			WeaponMesh->SetCollisionProfileName(TEXT("PhysicsActor"));
			WeaponMesh->AddAngularImpulse(FVector(1000, 500, 0));
		}
	}
}
コード例 #14
0
void FLODUtilities::RefreshLODChange(const USkeletalMesh* SkeletalMesh)
{
	for (FObjectIterator Iter(USkeletalMeshComponent::StaticClass()); Iter; ++Iter)
	{
		USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>(*Iter);
		if  (SkeletalMeshComponent->SkeletalMesh == SkeletalMesh)
		{
			// it needs to recreate IF it already has been created
			if (SkeletalMeshComponent->IsRegistered())
			{
				SkeletalMeshComponent->UpdateLODStatus();
				SkeletalMeshComponent->MarkRenderStateDirty();
			}
		}
	}
}
コード例 #15
0
FVector FObserveBoneEditMode::GetWidgetLocation() const
{
	USkeletalMeshComponent* SkelComp = GetAnimPreviewScene().GetPreviewMeshComponent();
	USkeleton* Skeleton = SkelComp->SkeletalMesh->Skeleton;
	FVector WidgetLoc = FVector::ZeroVector;

	int32 MeshBoneIndex = SkelComp->GetBoneIndex(GraphNode->Node.BoneToObserve.BoneName);

	if (MeshBoneIndex != INDEX_NONE)
	{
		const FTransform BoneTM = SkelComp->GetBoneTransform(MeshBoneIndex);
		WidgetLoc = BoneTM.GetLocation();
	}

	return WidgetLoc;
}
コード例 #16
0
void FGameplayAbilityActorInfo::InitFromActor(AActor *InOwnerActor, AActor *InAvatarActor, UAbilitySystemComponent* InAbilitySystemComponent)
{
	check(InOwnerActor);
	check(InAbilitySystemComponent);

	OwnerActor = InOwnerActor;
	AvatarActor = InAvatarActor;
	AbilitySystemComponent = InAbilitySystemComponent;

	// Look for a player controller or pawn in the owner chain.
	AActor *TestActor = InOwnerActor;
	while (TestActor)
	{
		if (APlayerController * CastPC = Cast<APlayerController>(TestActor))
		{
			PlayerController = CastPC;
			break;
		}

		if (APawn * Pawn = Cast<APawn>(TestActor))
		{
			PlayerController = Cast<APlayerController>(Pawn->GetController());
			break;
		}

		TestActor = TestActor->GetOwner();
	}

	if (AvatarActor.Get())
	{
		// Grab Components that we care about
		USkeletalMeshComponent * SkelMeshComponent = AvatarActor->FindComponentByClass<USkeletalMeshComponent>();
		if (SkelMeshComponent)
		{
			this->AnimInstance = SkelMeshComponent->GetAnimInstance();
		}

		MovementComponent = AvatarActor->FindComponentByClass<UMovementComponent>();
	}
	else
	{
		MovementComponent = NULL;
		AnimInstance = NULL;
	}
}
コード例 #17
0
PyObject *py_ue_get_anim_instance(ue_PyUObject *self, PyObject * args)
{

	ue_py_check(self);

	if (!self->ue_object->IsA<USkeletalMeshComponent>())
		return PyErr_Format(PyExc_Exception, "uobject is not a USkeletalMeshComponent");

	USkeletalMeshComponent *skeletal = (USkeletalMeshComponent *)self->ue_object;

	UAnimInstance *anim = skeletal->GetAnimInstance();
	if (!anim)
	{
		Py_INCREF(Py_None);
		return Py_None;
	}

	Py_RETURN_UOBJECT((UObject *)anim);
}
コード例 #18
0
//void AARWeapon::OnRep_WeaponOwner()
//{
//	if (WeaponOwner)
//		SetWeaponOwner(WeaponOwner);
//}
//void AARWeapon::SetWeaponOwner(AARCharacter* NewOwner)
//{
//	WeaponOwner = NewOwner;
//	SetOwner(NewOwner);
//}
void AARWeapon::AttachWeapon()
{
	if (ARCharacterOwner)
	{
		// Remove and hide both first and third person meshes

		// For locally controller players we attach both weapons and let the bOnlyOwnerSee, bOwnerNoSee flags deal with visibility.
		//FName AttachPoint = WeaponOwner->GetWeaponAttachPoint();
		if (ARCharacterOwner->IsLocallyControlled() == true)
		{
			USkeletalMeshComponent* PawnMesh3p = ARCharacterOwner->GetMesh();
			WeaponMesh->SetHiddenInGame(false);
			WeaponMesh->AttachTo(PawnMesh3p, "TestSocket");
		}
		else
		{
			USkeletalMeshComponent* UseWeaponMesh = WeaponMesh;
			USkeletalMeshComponent* UsePawnMesh = ARCharacterOwner->GetMesh();
			UseWeaponMesh->AttachTo(UsePawnMesh, "TestSocket");
			UseWeaponMesh->SetHiddenInGame(false);
		}
	}
}
FTransform UPhysicsConstraintComponent::GetBodyTransformInternal(EConstraintFrame::Type Frame, FName InBoneName) const
{
	UPrimitiveComponent* PrimComp = GetComponentInternal(Frame);
	if(!PrimComp)
	{
		return FTransform::Identity;
	}
	  
	//Use ComponentToWorld by default for all components
	FTransform ResultTM = PrimComp->ComponentToWorld;
		
	// Skeletal case
	USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(PrimComp);
	if(SkelComp != NULL)
	{
		int32 BoneIndex = SkelComp->GetBoneIndex(InBoneName);
		if(BoneIndex != INDEX_NONE)
		{	
			ResultTM = SkelComp->GetBoneTransform(BoneIndex);
		}
	}

	return ResultTM;
}
コード例 #20
0
void FAnimNode_AimOffsetLookAt::UpdateFromLookAtTarget(FPoseContext& LocalPoseContext)
{
    const FBoneContainer& RequiredBones = LocalPoseContext.Pose.GetBoneContainer();
    if (RequiredBones.GetSkeletalMeshAsset())
    {
        const USkeletalMeshSocket* Socket = RequiredBones.GetSkeletalMeshAsset()->FindSocket(SourceSocketName);
        if (Socket)
        {
            const FTransform SocketLocalTransform = Socket->GetSocketLocalTransform();

            FBoneReference SocketBoneReference;
            SocketBoneReference.BoneName = Socket->BoneName;
            SocketBoneReference.Initialize(RequiredBones);

            if (SocketBoneReference.IsValid(RequiredBones))
            {
                const FCompactPoseBoneIndex SocketBoneIndex = SocketBoneReference.GetCompactPoseIndex(RequiredBones);

                FCSPose<FCompactPose> GlobalPose;
                GlobalPose.InitPose(LocalPoseContext.Pose);

                USkeletalMeshComponent* Component = LocalPoseContext.AnimInstanceProxy->GetSkelMeshComponent();
                AActor* Actor = Component ? Component->GetOwner() : nullptr;

                if (Component && Actor &&  BlendSpace)
                {
                    const FTransform ActorTransform = Actor->GetTransform();

                    const FTransform BoneTransform = GlobalPose.GetComponentSpaceTransform(SocketBoneIndex);
                    const FTransform SocketWorldTransform = SocketLocalTransform * BoneTransform * Component->ComponentToWorld;

                    // Convert Target to Actor Space
                    const FTransform TargetWorldTransform(LookAtLocation);

                    const FVector DirectionToTarget = ActorTransform.InverseTransformVectorNoScale(TargetWorldTransform.GetLocation() - SocketWorldTransform.GetLocation()).GetSafeNormal();
                    const FVector CurrentDirection = ActorTransform.InverseTransformVectorNoScale(SocketWorldTransform.GetUnitAxis(EAxis::X));

                    const FVector AxisX = FVector::ForwardVector;
                    const FVector AxisY = FVector::RightVector;
                    const FVector AxisZ = FVector::UpVector;

                    const FVector2D CurrentCoords = FMath::GetAzimuthAndElevation(CurrentDirection, AxisX, AxisY, AxisZ);
                    const FVector2D TargetCoords = FMath::GetAzimuthAndElevation(DirectionToTarget, AxisX, AxisY, AxisZ);
                    const FVector BlendInput(
                        FRotator::NormalizeAxis(FMath::RadiansToDegrees(TargetCoords.X - CurrentCoords.X)),
                        FRotator::NormalizeAxis(FMath::RadiansToDegrees(TargetCoords.Y - CurrentCoords.Y)),
                        0.f);

                    // Set X and Y, so ticking next frame is based on correct weights.
                    X = BlendInput.X;
                    Y = BlendInput.Y;

                    // Generate BlendSampleDataCache from inputs.
                    BlendSpace->GetSamplesFromBlendInput(BlendInput, BlendSampleDataCache);

                    if (CVarAimOffsetLookAtDebug.GetValueOnAnyThread() == 1)
                    {
                        DrawDebugLine(Component->GetWorld(), SocketWorldTransform.GetLocation(), TargetWorldTransform.GetLocation(), FColor::Green);
                        DrawDebugLine(Component->GetWorld(), SocketWorldTransform.GetLocation(), SocketWorldTransform.GetLocation() + SocketWorldTransform.GetUnitAxis(EAxis::X) * (TargetWorldTransform.GetLocation() - SocketWorldTransform.GetLocation()).Size(), FColor::Red);
                        DrawDebugCoordinateSystem(Component->GetWorld(), ActorTransform.GetLocation(), ActorTransform.GetRotation().Rotator(), 100.f);

                        FString DebugString = FString::Printf(TEXT("Socket (X:%f, Y:%f), Target (X:%f, Y:%f), Result (X:%f, Y:%f)")
                                                              , FMath::RadiansToDegrees(CurrentCoords.X)
                                                              , FMath::RadiansToDegrees(CurrentCoords.Y)
                                                              , FMath::RadiansToDegrees(TargetCoords.X)
                                                              , FMath::RadiansToDegrees(TargetCoords.Y)
                                                              , BlendInput.X
                                                              , BlendInput.Y);
                        GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0.f, FColor::Red, DebugString, false);
                    }
                }
            }
        }
    }
}
コード例 #21
0
void UBuoyancyForceComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// If disabled or we are not attached to a parent component, return.
	if (!bIsActive || !GetAttachParent()) return;

	if (!OceanManager) return;

	UPrimitiveComponent* BasePrimComp = Cast<UPrimitiveComponent>(GetAttachParent());
	if (!BasePrimComp) return;

	if (!BasePrimComp->IsSimulatingPhysics())
	{
		if (!SnapToSurfaceIfNoPhysics) return;

		UE_LOG(LogTemp, Warning, TEXT("Running in no physics mode.."));

		float waveHeight = OceanManager->GetWaveHeightValue(BasePrimComp->GetComponentLocation(), World, true, TwoGerstnerIterations).Z;
		BasePrimComp->SetWorldLocation(FVector(BasePrimComp->GetComponentLocation().X, BasePrimComp->GetComponentLocation().Y, waveHeight));
		return;
	}

	//Get gravity
	float Gravity = BasePrimComp->GetPhysicsVolume()->GetGravityZ();

	//--------------- If Skeletal ---------------
	USkeletalMeshComponent* SkeletalComp = Cast<USkeletalMeshComponent>(GetAttachParent());
	if (SkeletalComp && ApplyForceToBones)
	{
		TArray<FName> BoneNames;
		SkeletalComp->GetBoneNames(BoneNames);

		for (int32 Itr = 0; Itr < BoneNames.Num(); Itr++)
		{
			FBodyInstance* BI = SkeletalComp->GetBodyInstance(BoneNames[Itr], false);
			if (BI && BI->IsValidBodyInstance()
				&& BI->bEnableGravity) //Buoyancy doesn't exist without gravity
			{
				bool isUnderwater = false;
				//FVector worldBoneLoc = SkeletalComp->GetBoneLocation(BoneNames[Itr]);
				FVector worldBoneLoc = BI->GetCOMPosition(); //Use center of mass of the bone's physics body instead of bone's location
				FVector waveHeight = OceanManager->GetWaveHeightValue(worldBoneLoc, World, true, TwoGerstnerIterations);

				float BoneDensity = MeshDensity;
				float BoneTestRadius = FMath::Abs(TestPointRadius);
				float SignedBoneRadius = FMath::Sign(Gravity) * TestPointRadius; //Direction of radius (test radius is actually a Z offset, should probably rename it!). Just in case we need an upside down world.

				//Get density & radius from the override array, if available.
				for (int pointIndex = 0; pointIndex < BoneOverride.Num(); pointIndex++)
				{
					FStructBoneOverride Override = BoneOverride[pointIndex];

					if (Override.BoneName.IsEqual(BoneNames[Itr]))
					{
						BoneDensity = Override.Density;
						BoneTestRadius = FMath::Abs(Override.TestRadius);
						SignedBoneRadius = FMath::Sign(Gravity) * BoneTestRadius;
					}
				}

				//If test point radius is below water surface, add buoyancy force.
				if (waveHeight.Z > (worldBoneLoc.Z + SignedBoneRadius))
				{
					isUnderwater = true;

					float DepthMultiplier = (waveHeight.Z - (worldBoneLoc.Z + SignedBoneRadius)) / (BoneTestRadius * 2);
					DepthMultiplier = FMath::Clamp(DepthMultiplier, 0.f, 1.f);

					float Mass = SkeletalComp->CalculateMass(BoneNames[Itr]); //Mass of this specific bone's physics body

					 /**
					* --------
					* Buoyancy force formula: (Volume(Mass / Density) * Fluid Density * -Gravity) / Total Points * Depth Multiplier
					* --------
					*/
					float BuoyancyForceZ = Mass / BoneDensity * FluidDensity * -Gravity * DepthMultiplier;

					//Velocity damping.
					FVector DampingForce = -BI->GetUnrealWorldVelocity() * VelocityDamper * Mass * DepthMultiplier;

					//Experimental xy wave force
					if (EnableWaveForces)
					{
						float waveVelocity = FMath::Clamp(BI->GetUnrealWorldVelocity().Z, -20.f, 150.f) * (1 - DepthMultiplier);
						DampingForce += FVector(OceanManager->GlobalWaveDirection.X, OceanManager->GlobalWaveDirection.Y, 0) * Mass * waveVelocity * WaveForceMultiplier;
					}

					//Add force to this bone
					BI->AddForce(FVector(DampingForce.X, DampingForce.Y, DampingForce.Z + BuoyancyForceZ));
					//BasePrimComp->AddForceAtLocation(FVector(DampingForce.X, DampingForce.Y, DampingForce.Z + BuoyancyForceZ), worldBoneLoc, BoneNames[Itr]);
				}

				//Apply fluid damping & clamp velocity
				if (isUnderwater)
				{
					BI->SetLinearVelocity(-BI->GetUnrealWorldVelocity() * (FluidLinearDamping / 10), true);
					BI->SetAngularVelocity(-BI->GetUnrealWorldAngularVelocity() * (FluidAngularDamping / 10), true);

					//Clamp the velocity to MaxUnderwaterVelocity
					if (ClampMaxVelocity && BI->GetUnrealWorldVelocity().Size() > MaxUnderwaterVelocity)
					{
						FVector	Velocity = BI->GetUnrealWorldVelocity().GetSafeNormal() * MaxUnderwaterVelocity;
						BI->SetLinearVelocity(Velocity, false);
					}
				}

				if (DrawDebugPoints)
				{
					FColor DebugColor = FLinearColor(0.8, 0.7, 0.2, 0.8).ToRGBE();
					if (isUnderwater) { DebugColor = FLinearColor(0, 0.2, 0.7, 0.8).ToRGBE(); } //Blue color underwater, yellow out of watter
					DrawDebugSphere(World, worldBoneLoc, BoneTestRadius, 8, DebugColor);
				}
			}
		}
		return;
	}
	//--------------------------------------------------------

	float TotalPoints = TestPoints.Num();
	if (TotalPoints < 1) return;

	int PointsUnderWater = 0;
	for (int pointIndex = 0; pointIndex < TotalPoints; pointIndex++)
	{
		if (!TestPoints.IsValidIndex(pointIndex)) return; //Array size changed during runtime

		bool isUnderwater = false;
		FVector testPoint = TestPoints[pointIndex];
		FVector worldTestPoint = BasePrimComp->GetComponentTransform().TransformPosition(testPoint);
		FVector waveHeight = OceanManager->GetWaveHeightValue(worldTestPoint, World, !EnableWaveForces, TwoGerstnerIterations);

		//Direction of radius (test radius is actually a Z offset, should probably rename it!). Just in case we need an upside down world.
		float SignedRadius = FMath::Sign(BasePrimComp->GetPhysicsVolume()->GetGravityZ()) * TestPointRadius;

		//If test point radius is below water surface, add buoyancy force.
		if (waveHeight.Z > (worldTestPoint.Z + SignedRadius)
			&& BasePrimComp->IsGravityEnabled()) //Buoyancy doesn't exist without gravity
		{
			PointsUnderWater++;
			isUnderwater = true;

			float DepthMultiplier = (waveHeight.Z - (worldTestPoint.Z + SignedRadius)) / (TestPointRadius * 2);
			DepthMultiplier = FMath::Clamp(DepthMultiplier, 0.f, 1.f);

			//If we have a point density override, use the overridden value instead of MeshDensity
			float PointDensity = PointDensityOverride.IsValidIndex(pointIndex) ? PointDensityOverride[pointIndex] : MeshDensity;

			/**
			* --------
			* Buoyancy force formula: (Volume(Mass / Density) * Fluid Density * -Gravity) / Total Points * Depth Multiplier
			* --------
			*/
			float BuoyancyForceZ = BasePrimComp->GetMass() / PointDensity * FluidDensity * -Gravity / TotalPoints * DepthMultiplier;

			//Experimental velocity damping using VelocityAtPoint.
			FVector DampingForce = -GetUnrealVelocityAtPoint(BasePrimComp, worldTestPoint) * VelocityDamper * BasePrimComp->GetMass() * DepthMultiplier;

			//Experimental xy wave force
			if (EnableWaveForces)
			{
				DampingForce += BasePrimComp->GetMass() * FVector2D(waveHeight.X, waveHeight.Y).Size() * FVector(OceanManager->GlobalWaveDirection.X, OceanManager->GlobalWaveDirection.Y, 0) * WaveForceMultiplier / TotalPoints;
				//float waveVelocity = FMath::Clamp(GetUnrealVelocityAtPoint(BasePrimComp, worldTestPoint).Z, -20.f, 150.f) * (1 - DepthMultiplier);
				//DampingForce += OceanManager->GlobalWaveDirection * BasePrimComp->GetMass() * waveVelocity * WaveForceMultiplier / TotalPoints;
			}

			//Add force for this test point
			BasePrimComp->AddForceAtLocation(FVector(DampingForce.X, DampingForce.Y, DampingForce.Z + BuoyancyForceZ), worldTestPoint);
		}

		if (DrawDebugPoints)
		{
			FColor DebugColor = FLinearColor(0.8, 0.7, 0.2, 0.8).ToRGBE();
			if (isUnderwater) { DebugColor = FLinearColor(0, 0.2, 0.7, 0.8).ToRGBE(); } //Blue color underwater, yellow out of watter
			DrawDebugSphere(World, worldTestPoint, TestPointRadius, 8, DebugColor);
		}
	}

	//Clamp the velocity to MaxUnderwaterVelocity if there is any point underwater
	if (ClampMaxVelocity && PointsUnderWater > 0
		&& BasePrimComp->GetPhysicsLinearVelocity().Size() > MaxUnderwaterVelocity)
	{
		FVector	Velocity = BasePrimComp->GetPhysicsLinearVelocity().GetSafeNormal() * MaxUnderwaterVelocity;
		BasePrimComp->SetPhysicsLinearVelocity(Velocity);
	}

	//Update damping based on number of underwater test points
	BasePrimComp->SetLinearDamping(_baseLinearDamping + FluidLinearDamping / TotalPoints * PointsUnderWater);
	BasePrimComp->SetAngularDamping(_baseAngularDamping + FluidAngularDamping / TotalPoints * PointsUnderWater);
}
コード例 #22
0
AActor* UAnimInstance::GetOwningActor()
{
	USkeletalMeshComponent* OwnerComponent = GetSkelMeshComponent();
	return OwnerComponent->GetOwner();
}
コード例 #23
0
void FFaceFXAnimationTrackInstance::Update(EMovieSceneUpdateData& UpdateData, const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, class IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance)
{
	check(AnimationTrack);

	//Find the section to update
	UFaceFXAnimationSection* AnimSection = Cast<UFaceFXAnimationSection>(AnimationTrack->GetSectionAtTime(UpdateData.Position));
	if (!AnimSection || !AnimSection->IsActive())
	{
		StopAllPlayback(RuntimeObjects);
		CurrentActiveSection = nullptr;
		return;
	}

	const float PlaybackLocation = CalcPlaybackLocation(UpdateData.Position, AnimSection);

	//update the current anim section within this track
	const bool IsNewAnimSection = CurrentActiveSection != AnimSection;
	CurrentActiveSection = AnimSection;
	
	//update the assigned runtime objects for this track
	for (int32 i = 0; i < RuntimeObjects.Num(); ++i)
	{
		UObject* RuntimeObject = RuntimeObjects[i].Get();
		UFaceFXComponent* FaceFXComponent = GetFaceFXComponent(RuntimeObject);
		if (!FaceFXComponent)
		{
			continue;
		}

		//may be null if the skel mesh component id is unset and there is no character setup on the component
		USkeletalMeshComponent* SkelMeshTarget = FaceFXComponent->GetSkelMeshTarget(AnimSection->GetComponent());

		//Always stop when we switch track keys to prevent playing animations when switching backward after the end of another track animation
		//Thats because we don't check here how long the animation actually plays and rely on the JumpTo/Play functionality alone to determine that
		if (IsNewAnimSection)
		{
			FaceFXComponent->Stop(SkelMeshTarget);
		}

		const EMovieScenePlayerStatus::Type State = Player.GetPlaybackStatus();

		const bool bScrub = State != EMovieScenePlayerStatus::Playing;
		const bool bPaused = State == EMovieScenePlayerStatus::Stopped && UpdateData.Position == UpdateData.LastPosition;

		//playing backwards or jumping
		const FFaceFXAnimId& AnimId = AnimSection->GetAnimationId();

		bool UpdateAnimation = true;

		if (State == EMovieScenePlayerStatus::Playing)
		{
			//Playback mode
			if (!IsNewAnimSection && FaceFXComponent->IsPlaying(SkelMeshTarget, RuntimeObject))
			{
				//No need to updating the FaceFXComponent
				UpdateAnimation = false;
			}
		}

		if (UpdateAnimation)
		{
			bool JumpSucceeded = false;
			if (bPaused)
			{
				FaceFXComponent->Pause(SkelMeshTarget);
			}
			else
			{
				//jump if not stopping
				if (AnimId.IsValid())
				{
					//play by animation id
					JumpSucceeded = FaceFXComponent->JumpToById(PlaybackLocation, bScrub, AnimId.Group, AnimId.Name, false, SkelMeshTarget, RuntimeObject);
				}
				else if (UFaceFXAnim* FaceFXAnim = AnimSection->GetAnimation(FaceFXComponent))
				{
					//play by animation
					JumpSucceeded = FaceFXComponent->JumpTo(PlaybackLocation, bScrub, FaceFXAnim, false, SkelMeshTarget, RuntimeObject);
				}

				if (!JumpSucceeded)
				{
					//jump to failed -> i.e. out of range on non looping animation
					FaceFXComponent->Stop(SkelMeshTarget);
				}
			}
		}

		if (SkelMeshTarget)
		{
			//enforce an update on the bones to trigger blend nodes
			SkelMeshTarget->RefreshBoneTransforms();
		}
	}
}
コード例 #24
0
FVector AShooterWeapon::GetMuzzleDirection() const
{
	USkeletalMeshComponent* UseMesh = GetWeaponMesh();
	return UseMesh->GetSocketRotation(MuzzleAttachPoint).Vector();
}