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); }
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; }
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? } } } } }
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 ); } } }
void UAnimInstance::SetMorphTarget(FName MorphTargetName, float Value) { USkeletalMeshComponent * Component = GetOwningComponent(); if (Component) { Component->SetMorphTarget(MorphTargetName, Value); } }
void UAnimInstance::ClearMorphTargets() { USkeletalMeshComponent * Component = GetOwningComponent(); if (Component) { Component->ClearMorphTargets(); } }
FVector AARCharacter::GetMainWeaponSocket(const FName& Socket) const { USkeletalMeshComponent* Component = GetMainWeaponMesh(); if (!Component) return GetMesh()->GetSocketLocation(TEXT("headSocket")); return Component->GetSocketLocation(Socket); }
APawn* UAnimInstance::TryGetPawnOwner() { USkeletalMeshComponent* OwnerComponent = GetSkelMeshComponent(); if (AActor* OwnerActor = OwnerComponent->GetOwner()) { return Cast<APawn>(OwnerActor); } return NULL; }
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); } }
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; }
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)); } } }
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(); } } } }
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; }
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; } }
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); }
//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; }
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); } } } } } }
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); }
AActor* UAnimInstance::GetOwningActor() { USkeletalMeshComponent* OwnerComponent = GetSkelMeshComponent(); return OwnerComponent->GetOwner(); }
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(); } } }
FVector AShooterWeapon::GetMuzzleDirection() const { USkeletalMeshComponent* UseMesh = GetWeaponMesh(); return UseMesh->GetSocketRotation(MuzzleAttachPoint).Vector(); }