diff --git a/Source/CharacterPlugin/CharacterPlugin.Build.cs b/Source/CharacterPlugin/CharacterPlugin.Build.cs index 5cf9d10ff5d5933582585149c034844f53e25718..a4b8314c2bfff78de1e15ba6a2aa9166ec00518e 100644 --- a/Source/CharacterPlugin/CharacterPlugin.Build.cs +++ b/Source/CharacterPlugin/CharacterPlugin.Build.cs @@ -3,15 +3,17 @@ using System.IO; public class CharacterPlugin : ModuleRules { - public CharacterPlugin(ReadOnlyTargetRules Target) : base(Target) - { + public CharacterPlugin(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; - PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + PrivateIncludePaths.AddRange(new string[] { }); + PublicIncludePaths.AddRange(new string[] { }); - PrivateIncludePaths.AddRange(new string[] { }); - PublicIncludePaths.AddRange(new string[] { }); - - PublicDependencyModuleNames.AddRange(new string[] { "CoreUObject", "Engine", "Core", "DisplayCluster", "AIModule", "Projects", "NavigationSystem", "AIModule", "UniversalLogging", "RWTHVRToolkit", "VAPlugin", "AnimGraphRuntime" }); - - } + PublicDependencyModuleNames.AddRange(new string[] + { + "CoreUObject", "Engine", "Core", "DisplayCluster", "AIModule", "Projects", "NavigationSystem", "AIModule", + "UniversalLogging", "RWTHVRToolkit", "VAPlugin", "AnimGraphRuntime" + }); + } } \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/AnimNodes/AnimNode_VHGazing.cpp b/Source/CharacterPlugin/Private/AnimNodes/AnimNode_VHGazing.cpp index 2d2dc325f521d4682d7b0d342873381709f18169..8ee8574a6f873fb778f81da4017f068fb53f69e3 100644 --- a/Source/CharacterPlugin/Private/AnimNodes/AnimNode_VHGazing.cpp +++ b/Source/CharacterPlugin/Private/AnimNodes/AnimNode_VHGazing.cpp @@ -5,9 +5,8 @@ #include "AnimationRuntime.h" - - -void FAnimNode_VHGazing::Initialize_AnyThread(const FAnimationInitializeContext& Context) { +void FAnimNode_VHGazing::Initialize_AnyThread(const FAnimationInitializeContext& Context) +{ DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Initialize_AnyThread) FAnimNode_Base::Initialize_AnyThread(Context); @@ -22,8 +21,7 @@ void FAnimNode_VHGazing::CacheBones_AnyThread(const FAnimationCacheBonesContext& InputPose.CacheBones(Context); const FBoneContainer& RequiredBones = Context.AnimInstanceProxy->GetRequiredBones(); - auto PrivateInitialize = [&](FGazingBoneData& BoneData) - { + auto PrivateInitialize = [&](FGazingBoneData& BoneData) { if (BoneData.TargetBone.BoneName == NAME_None) { UE_LOG(LogTemp, Error, TEXT("[FAnimNode_VHGazing] You need to specify a targetbone, which should be oriented towards the gaze target")) @@ -36,7 +34,8 @@ void FAnimNode_VHGazing::CacheBones_AnyThread(const FAnimationCacheBonesContext& } BoneData.CurrentRotation = FRotator::ZeroRotator; - if (BoneData.TargetBone.BoneName != NAME_None) { + if (BoneData.TargetBone.BoneName != NAME_None) + { BoneData.TargetBone.Initialize(RequiredBones); BoneData.DefaultTargetBoneTransform = FAnimationRuntime::GetComponentSpaceTransformRefPose(*RefSkel, BoneData.TargetBone.BoneIndex); @@ -71,7 +70,7 @@ void FAnimNode_VHGazing::Evaluate_AnyThread(FPoseContext& Output) { DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Evaluate_AnyThread) InputPose.Evaluate(Output); - + // dublicate the local pose to a component space one, since the computations are done in component space FComponentSpacePoseContext CSPoseContext(Output.AnimInstanceProxy); CSPoseContext.Pose.InitPose(CopyTemp(Output.Pose)); @@ -82,13 +81,13 @@ void FAnimNode_VHGazing::Evaluate_AnyThread(FPoseContext& Output) } -void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FComponentSpacePoseContext& CSPoseContext) { +void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FComponentSpacePoseContext& CSPoseContext) +{ // Update rotations one after another // We use data of the last frame to see whether, e.g., the eyes were able to reach their target // or whether, e.g., the head as to help out by also rotating further towards the target - // ************************* // Compute & Apply Torso // ************************* @@ -99,7 +98,8 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon FRotator TargetRotationTorso = GetRotationToTarget(TorsoBoneData, LocalPoseContext, CSPoseContext); TargetRotationTorso = VHGazingData.TorsoData.Alignment * TargetRotationTorso; - if (VHGazingData.bSupportClampedRotationByOtherParts) { + if (VHGazingData.bSupportClampedRotationByOtherParts) + { TargetRotationTorso += HeadBoneData.MissingRotationDueToClamp; } @@ -110,7 +110,6 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon ApplyRotation(TorsoBoneData, TorsoBoneData.CurrentRotation, LocalPoseContext, CSPoseContext); } - //now recompute and apply for head and eyes again with updated data (most code is identical!) // **************** @@ -128,7 +127,8 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon //remove the way that the torso already made TargetRotationHead -= TorsoBoneData.CurrentRotation; - if (VHGazingData.bSupportClampedRotationByOtherParts) { + if (VHGazingData.bSupportClampedRotationByOtherParts) + { //add the rotation that the eyes weren't able to make due to them being clamped at the gaze limits TargetRotationHead += 0.5f * (RightEyeBoneData.MissingRotationDueToClamp + LeftEyeBoneData.MissingRotationDueToClamp); } @@ -145,18 +145,17 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon FRotator MissingHead = PreClampedHead - TargetRotationHead; //store what part of the rotation the torso potentially has to take over in the next frame - if ((DistanceToClampHead > 1.f && MissingHead.IsNearlyZero()) || !MissingHead.IsNearlyZero()) { + if ((DistanceToClampHead > 1.f && MissingHead.IsNearlyZero()) || !MissingHead.IsNearlyZero()) + { // however, take the mean of this and last frame to avoid jittering HeadBoneData.MissingRotationDueToClamp = 0.5f * (HeadBoneData.MissingRotationDueToClamp + MissingHead); } //else we probably only reached the target because the troso helped, so don't set the missing part to 0 to avoid jitter - UpdateCurrentRotation(HeadBoneData, VHGazingData.HeadData, TargetRotationHead); ApplyRotation(HeadBoneData, HeadBoneData.CurrentRotation, LocalPoseContext, CSPoseContext); } - // **************** // Apply Eyes // **************** @@ -191,12 +190,14 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon // store what head and torso need to take over for next frame. // if this angele is small, we probably only reached the target because the head + torso helped, // so don't set the missing part to 0 directly to avoid jitter - if ((DistanceToClampRightEye > 1.f && MissingRight.IsNearlyZero()) || !MissingRight.IsNearlyZero()) { + if ((DistanceToClampRightEye > 1.f && MissingRight.IsNearlyZero()) || !MissingRight.IsNearlyZero()) + { // however, take the mean of this and last frame to avoid jittering RightEyeBoneData.MissingRotationDueToClamp = 0.5 * (RightEyeBoneData.MissingRotationDueToClamp + MissingRight); } - if ((DistanceToClampLeftEye > 1.f && MissingLeft.IsNearlyZero()) || !MissingLeft.IsNearlyZero()) { + if ((DistanceToClampLeftEye > 1.f && MissingLeft.IsNearlyZero()) || !MissingLeft.IsNearlyZero()) + { // however, take the mean of this and last frame to avoid jittering LeftEyeBoneData.MissingRotationDueToClamp = 0.5 * (LeftEyeBoneData.MissingRotationDueToClamp + MissingLeft); } @@ -210,9 +211,10 @@ void FAnimNode_VHGazing::UpdateRotations(FPoseContext& LocalPoseContext, FCompon ApplyRotation(LeftEyeBoneData, LeftEyeBoneData.CurrentRotation, LocalPoseContext, CSPoseContext); } -void FAnimNode_VHGazing::UpdateCurrentRotation(FGazingBoneData& GazingBoneData, const FGazingPartData& GazingPartData, const FRotator& TargetRotation) { +void FAnimNode_VHGazing::UpdateCurrentRotation(FGazingBoneData& GazingBoneData, const FGazingPartData& GazingPartData, const FRotator& TargetRotation) +{ - if(!GazingBoneData.bUseBlendshapeOutput && GazingBoneData.InfluenceBones.Num()==0) + if (!GazingBoneData.bUseBlendshapeOutput && GazingBoneData.InfluenceBones.Num() == 0) { //nothing is applied here, e.g. for torso bone in metahuman face animBP GazingBoneData.CurrentRotation = FRotator::ZeroRotator; @@ -234,17 +236,20 @@ void FAnimNode_VHGazing::UpdateCurrentRotation(FGazingBoneData& GazingBoneData, return; } - //we need to keep track how far this movement went to adapt speeds according to https://doi.org/10.1145/2724731 - if (Angle > GazingBoneData.AmplitudeCurrMovement) { + if (Angle > GazingBoneData.AmplitudeCurrMovement) + { GazingBoneData.AmplitudeCurrMovement = Angle; - if (Angle > 10.0f && GazingBoneData.TimeDelay == 0.0f) { //this number (10degree) is just a guess + if (Angle > 10.0f && GazingBoneData.TimeDelay == 0.0f) + { + //this number (10degree) is just a guess //only do Delay for larger movements GazingBoneData.TimeDelay = GazingPartData.DelayConstant + GazingPartData.DelayLinear * Angle; } } - if (GazingBoneData.TimeDelay > 0.0f) { + if (GazingBoneData.TimeDelay > 0.0f) + { GazingBoneData.TimeDelay -= DeltaTime; return; // since we are delaying right now } @@ -285,12 +290,11 @@ void FAnimNode_VHGazing::ApplyRotation(FGazingBoneData& GazingBoneData, FRotator //actually apply the current rotation //check whether we do this via blendshapes or bones: - if(GazingBoneData.bUseBlendshapeOutput) + if (GazingBoneData.bUseBlendshapeOutput) { //do it via blendshapes: USkeleton* Skeleton = PoseContext.AnimInstanceProxy->GetSkeleton(); - auto ApplyBlendshapeRotation = [&](float Angle, float FullAngle, FName PositiveBlendshape, FName NegativeBlendshape) - { + auto ApplyBlendshapeRotation = [&](float Angle, float FullAngle, FName PositiveBlendshape, FName NegativeBlendshape) { float PositiveActivation = FMath::Clamp(Angle / FullAngle, 0.0f, 1.0f); float NegativeActivation = FMath::Clamp(-1.0f * Angle / FullAngle, 0.0f, 1.0f); @@ -302,7 +306,8 @@ void FAnimNode_VHGazing::ApplyRotation(FGazingBoneData& GazingBoneData, FRotator ApplyBlendshapeRotation(Rotation.Yaw, GazingBoneData.YawAngleAtFull, GazingBoneData.BlendshapeNameRight, GazingBoneData.BlendshapeNameLeft); ApplyBlendshapeRotation(Rotation.Pitch, GazingBoneData.PitchAngleAtFull, GazingBoneData.BlendshapeNameUp, GazingBoneData.BlendshapeNameDown); } - else { + else + { //do it via bones: const FBoneContainer& BoneContainer = PoseContext.Pose.GetBoneContainer(); @@ -341,7 +346,8 @@ FRotator FAnimNode_VHGazing::GetRotationToTarget(FGazingBoneData& GazingBoneData check(AnimProxy); FVector TargetLocation = VHGazingData.GazeTargetLocation; - if (bEyes && VHGazingData.EyesOnlyGazeTarget.IsSet()) { + if (bEyes && VHGazingData.EyesOnlyGazeTarget.IsSet()) + { TargetLocation = VHGazingData.EyesOnlyGazeTarget.GetValue(); } @@ -365,10 +371,10 @@ FRotator FAnimNode_VHGazing::GetYawPitchRotationBetween(FVector From, FVector To FVector2D ToSpherical = To.UnitCartesianToSpherical(); //Output spherical Theta[0] will be in the range [0, PI], and output Phi[1] will be in the range [-PI, PI]. - float Yaw = FMath::RadiansToDegrees(ToSpherical[1] - FromSpherical[1]); + float Yaw = FMath::RadiansToDegrees(ToSpherical[1] - FromSpherical[1]); float Pitch = FMath::RadiansToDegrees(ToSpherical[0] - FromSpherical[0]) * -1; //pitch is defined other way around - Yaw = FRotator::NormalizeAxis(Yaw); + Yaw = FRotator::NormalizeAxis(Yaw); Pitch = FRotator::NormalizeAxis(Pitch); return FRotator(Pitch, Yaw, 0.0f); @@ -376,14 +382,16 @@ FRotator FAnimNode_VHGazing::GetYawPitchRotationBetween(FVector From, FVector To FRotator FAnimNode_VHGazing::TransformToAgentForward(FRotator Rotation) const { - if (AgentDefaultForward != FVector(0, 1, 0)) { + if (AgentDefaultForward != FVector(0, 1, 0)) + { UE_LOG(LogTemp, Warning, TEXT("This method currently works only for agents facing in positive Y direction!")) } return FRotator(Rotation.Roll, Rotation.Yaw, -Rotation.Pitch); } -FRotator FAnimNode_VHGazing::ClampRotation(FRotator Rotation, const FGazingPartData& GazingPartData, float& MinDistanceToClamp) const { +FRotator FAnimNode_VHGazing::ClampRotation(FRotator Rotation, const FGazingPartData& GazingPartData, float& MinDistanceToClamp) const +{ FRotator OutRotation = Rotation; OutRotation.Yaw = FMath::Clamp(OutRotation.Yaw, -GazingPartData.MaxYaw, GazingPartData.MaxYaw); @@ -397,5 +405,4 @@ FRotator FAnimNode_VHGazing::ClampRotation(FRotator Rotation, const FGazingPartD MinDistanceToClamp = FMath::Min(GazingPartData.MaxPitch - OutRotation.Pitch, MinDistanceToClamp); return OutRotation; -} - +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/AnimNodes/ModifyCurvesNode.cpp b/Source/CharacterPlugin/Private/AnimNodes/ModifyCurvesNode.cpp index f5af60457e4da4542cb74107e64bc644306003fd..8748f23a5931f82b07c125fc06d06d8eb86013cf 100644 --- a/Source/CharacterPlugin/Private/AnimNodes/ModifyCurvesNode.cpp +++ b/Source/CharacterPlugin/Private/AnimNodes/ModifyCurvesNode.cpp @@ -35,7 +35,8 @@ void FModifyCurvesNode::Evaluate_AnyThread(FPoseContext& Output) Output = SourceData; - if (FacialExpressionsInstance != nullptr) { + if (FacialExpressionsInstance != nullptr) + { const TMap<FName, float> AnimData = FacialExpressionsInstance->GetCurrentAnimationValues(); @@ -88,11 +89,13 @@ void FModifyCurvesNode::Evaluate_AnyThread(FPoseContext& Output) } - if (FaceAnimInstance != nullptr) { + if (FaceAnimInstance != nullptr) + { const FAnimationData AnimData = FaceAnimInstance->GetAnimData(); - if (AnimData.BlendshapeNames.Num() > AnimData.CurrentFrameValues.Num()) { + if (AnimData.BlendshapeNames.Num() > AnimData.CurrentFrameValues.Num()) + { return; } diff --git a/Source/CharacterPlugin/Private/CharacterPlugin.cpp b/Source/CharacterPlugin/Private/CharacterPlugin.cpp index c2ec58f81109afe9a4b2cee3151242a6f1262eba..3d167e446b9c8642fa83b5f187e8c4ad867a9b2e 100644 --- a/Source/CharacterPlugin/Private/CharacterPlugin.cpp +++ b/Source/CharacterPlugin/Private/CharacterPlugin.cpp @@ -4,15 +4,12 @@ #include "CharacterPluginLogging.h" -void FCharacterPluginModule::StartupModule () +void FCharacterPluginModule::StartupModule() { - CharacterPluginLogging::InitializeLoggingStreams(); + CharacterPluginLogging::InitializeLoggingStreams(); } -void FCharacterPluginModule::ShutdownModule() -{ - -} +void FCharacterPluginModule::ShutdownModule() {} #undef LOCTEXT_NAMESPACE diff --git a/Source/CharacterPlugin/Private/Crowds/Predictive.cpp b/Source/CharacterPlugin/Private/Crowds/Predictive.cpp index 4a23273efac9ecefe27556744b37228c3e9619f7..3e35c1c046f565a5804481228289648d9c4c42c3 100644 --- a/Source/CharacterPlugin/Private/Crowds/Predictive.cpp +++ b/Source/CharacterPlugin/Private/Crowds/Predictive.cpp @@ -29,7 +29,7 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) AVirtualHuman* Agent = Cast<AVirtualHuman>(GetOwner()); //VH_DEBUG("%s delta time: %f", *Agent->GetName(), LastDeltaTime) //VH_DEBUG("%s start velocity im cm/s, %f, %f, %f", *Agent->GetName(), Velocity[0], Velocity[1], Velocity[2]) - + if (Agent == nullptr) { Velocity = FVector::ZeroVector; @@ -50,7 +50,7 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) } */ TArray<AVirtualHuman*> Neighbours; - for (AActor *a : Actors) + for (AActor* a : Actors) { AVHsManager* Manager = Cast<AVHsManager>(a); if (Manager != nullptr) @@ -68,7 +68,6 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) return; } - /************************************************************************/ /* SETUP START VALUES */ /************************************************************************/ @@ -84,16 +83,16 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) FVector CurrentLocation = Agent->GetActorLocation() / 100.0f; FVector CurrentVelocity = Agent->GetVelocity() / 100.0f; //VH_DEBUG("%s current velocity im m/s: %f, %f, %f", *Agent->GetName(), CurrentVelocity[0], CurrentVelocity[1], CurrentVelocity[2]) - + // goal force attracting the agents to it's goal FVector2D force((Velocity - CurrentVelocity) / REACTION_TIME); - + // safe distance agent prefers to keep from buildings etc. const float SAFE_DIST = WALL_DISTANCE + RADIUS; - + FVector2D desiredVel = FVector2D(CurrentVelocity) + force * LastDeltaTime; float desSpeed = (desiredVel).Size(); - + /************************************************************************/ /* WEIGHT ALL NEIGHBORS */ /************************************************************************/ @@ -116,9 +115,9 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) colliding = true; collidingSet.Empty(); } - + collidingSet.Add(TPair<float, const AActor*>(.0f, Neighbour)); - + if (collidingSet.Num() > collidingCount) { ++collidingCount; @@ -134,12 +133,10 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) } } - collidingSet.Sort([](const TPair<float, const AActor*>& A, const TPair<float, const AActor*>& B) - { + collidingSet.Sort([](const TPair<float, const AActor*>& A, const TPair<float, const AActor*>& B) { return A.Key < B.Key; }); - int count = 0; for (auto CollidingNeighbourPair : collidingSet) { @@ -190,7 +187,7 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) float angle = CrowdsPredictiveRandomStream.FRandRange(0.0f, 2.0f * PI); float dist = CrowdsPredictiveRandomStream.FRandRange(0.0f, 0.001f); force += dist * FVector2D(cos(angle), sin(angle)); - + // Cap the force to maxAcceleration if ((force).Size() > MAX_ACCELERATION) { @@ -202,7 +199,7 @@ void UPredictive::PostProcessVelocity(float LastDeltaTime, FVector& Velocity) /************************************************************************/ /* UPDATE THE AGENT'S VELOCITY */ /************************************************************************/ - Velocity = FVector((desiredVel + force * LastDeltaTime) * 100.f, Velocity.Z * 100.f); // assumes unit mass + Velocity = FVector((desiredVel + force * LastDeltaTime) * 100.f, Velocity.Z * 100.f); // assumes unit mass // VH_DEBUG("%s final velocity in m/s:, %f, %f, %f", *Agent->GetName(), Velocity[0], Velocity[1], Velocity[2]) } @@ -216,20 +213,20 @@ float UPredictive::RayCircleTTC(const FVector2D& Dir, const FVector2D& Center, f float b = -2.f * (Dir | Center); float c = (Center).SizeSquared() - (Radius * Radius); float discr = b * b - 4.f * a * c; - + if (discr < 0.f) { return INFINITY; } - + const float sqrtDiscr = sqrtf(discr); float t0 = (-b - sqrtDiscr) / (2.f * a); float t1 = (-b + sqrtDiscr) / (2.f * a); - + // If the points of collision have different signs, it means I'm already colliding - if ((t0 < 0.f && t1 > 0.f) || (t1 < 0.f && t0 > 0.f)) + if ((t0 < 0.f && t1 > 0.f) || (t1 < 0.f && t0 > 0.f)) return 0.f; - + if (t0 < t1 && t0 > 0.f) return t0; else if (t1 > 0.f) @@ -241,39 +238,39 @@ float UPredictive::RayCircleTTC(const FVector2D& Dir, const FVector2D& Center, f // after SAFE_DIST intoduction //const float SAFE_DIST2 = SAFE_DIST * SAFE_DIST; //auto Obstacles = Agent->GetObstacles(); //empty array in the current implementation if PawnStorm - /*for (auto Obstacle : Obstacles) +/*for (auto Obstacle : Obstacles) +{ + // TODO: Interaction with obstacles is, currently, defined strictly + // by COLLISIONS. Only if I'm going to collide with an obstacle is + // a force applied. This may be too naive. + // I'll have to investigate this. + + FVector2D nearPt; // set by distanceSqToPoint + float sqDist; // set by distanceSqToPoint + if (Obstacle.DistanceSqToPoint(FVector2D(CurrentLocation) * 100.0f, nearPt, sqDist) == LAST) continue; + nearPt /= 100.0f; + sqDist /= 10000.0f; + + if (SAFE_DIST2 > sqDist) { - // TODO: Interaction with obstacles is, currently, defined strictly - // by COLLISIONS. Only if I'm going to collide with an obstacle is - // a force applied. This may be too naive. - // I'll have to investigate this. - - FVector2D nearPt; // set by distanceSqToPoint - float sqDist; // set by distanceSqToPoint - if (Obstacle.DistanceSqToPoint(FVector2D(CurrentLocation) * 100.0f, nearPt, sqDist) == LAST) continue; - nearPt /= 100.0f; - sqDist /= 10000.0f; - - if (SAFE_DIST2 > sqDist) + // A repulsive force is actually possible + float dist = sqrtf(sqDist); + float num = SAFE_DIST - dist; + float distMradius = (dist - Radius) < PREDICTIVE_EPSILON ? PREDICTIVE_EPSILON : dist - Radius; + float denom = powf(distMradius, WALL_STEEPNESS); + FVector2D dir = (FVector2D(CurrentLocation) - nearPt).GetSafeNormal(); + float mag = num / denom; + force += dir * mag; + + if (Simulation->DebugDraw) { - // A repulsive force is actually possible - float dist = sqrtf(sqDist); - float num = SAFE_DIST - dist; - float distMradius = (dist - Radius) < PREDICTIVE_EPSILON ? PREDICTIVE_EPSILON : dist - Radius; - float denom = powf(distMradius, WALL_STEEPNESS); - FVector2D dir = (FVector2D(CurrentLocation) - nearPt).GetSafeNormal(); - float mag = num / denom; - force += dir * mag; - - if (Simulation->DebugDraw) - { - DrawDebugLine(Agent->GetWorld(), CurrentLocation * 100, (FVector(nearPt, CurrentLocation.Z)) * 100, - FColor::Yellow, false, Comp->LastDeltaTime); - } - else if (Simulation->DebugDraw) - { - DrawDebugLine(Agent->GetWorld(), CurrentLocation * 100, (FVector(nearPt, CurrentLocation.Z)) * 100, - FColor::Black, false, Comp->LastDeltaTime); - } + DrawDebugLine(Agent->GetWorld(), CurrentLocation * 100, (FVector(nearPt, CurrentLocation.Z)) * 100, + FColor::Yellow, false, Comp->LastDeltaTime); } - }*/ + else if (Simulation->DebugDraw) + { + DrawDebugLine(Agent->GetWorld(), CurrentLocation * 100, (FVector(nearPt, CurrentLocation.Z)) * 100, + FColor::Black, false, Comp->LastDeltaTime); + } + } +}*/ \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/Crowds/Spawner/AgentSpawner.cpp b/Source/CharacterPlugin/Private/Crowds/Spawner/AgentSpawner.cpp index 9642e3ee937c6f8c47eb4212326fa6af910a5488..3450c53e815f7f6cf1c51b04ea0965bd85bbfd22 100644 --- a/Source/CharacterPlugin/Private/Crowds/Spawner/AgentSpawner.cpp +++ b/Source/CharacterPlugin/Private/Crowds/Spawner/AgentSpawner.cpp @@ -14,7 +14,8 @@ void AAgentSpawner::Spawn() { GetWorld()->GetTimerManager().ClearTimer(SpawnTimerHandle); - if (RespawnRate > 0) { + if (RespawnRate > 0) + { GetWorld()->GetTimerManager().SetTimer(SpawnTimerHandle, this, &AAgentSpawner::Spawn, RespawnRate, false); } } diff --git a/Source/CharacterPlugin/Private/Crowds/Spawner/CircleSpawner.cpp b/Source/CharacterPlugin/Private/Crowds/Spawner/CircleSpawner.cpp index 90afbaf07ce4e78581dbd8da12513bb1958eb5d9..e7285f79fe85cb2f4b7ec6ef461ba1ca18b9fb07 100644 --- a/Source/CharacterPlugin/Private/Crowds/Spawner/CircleSpawner.cpp +++ b/Source/CharacterPlugin/Private/Crowds/Spawner/CircleSpawner.cpp @@ -6,11 +6,10 @@ #include "VHMovement.h" #include "CharacterPluginLogging.h" -void ACircleSpawner::BeginPlay() { +void ACircleSpawner::BeginPlay() {} -} - -void ACircleSpawner::Spawn() { +void ACircleSpawner::Spawn() +{ Super::Spawn(); // get our associated VHsManager @@ -21,13 +20,14 @@ void ACircleSpawner::Spawn() { } AVHsManager* Manager = Cast<AVHsManager>(VHsManager); - for (int i = 0; i < GroupSize; i++) { + for (int i = 0; i < GroupSize; i++) + { //VH_DEBUG("Actor location is: %s", *GetActorLocation().ToString()) FVector Position = GetActorLocation() + FVector(FVector2D(0, SpawnRadius).GetRotated(i * 360 / GroupSize), 0); //VH_DEBUG("Spawn position is is: %s", *Position.ToString()) AVirtualHuman* VH = Manager->SpawnVH(Position, true); - if(!VH) + if (!VH) { VH_ERROR("[ACircleSpawner::Spawn()] VH is nullptr"); continue; @@ -47,4 +47,4 @@ void ACircleSpawner::Spawn() { VHMovement->StoreAllWaypoints(); VHMovement->MoveToWaypoint(); } -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/Crowds/VHsManager.cpp b/Source/CharacterPlugin/Private/Crowds/VHsManager.cpp index 928d688d0d1c6a3a651fcc9e0866f35cb8dd05b6..1f0816fa738503c5fe159be286934b7e4aecb47f 100644 --- a/Source/CharacterPlugin/Private/Crowds/VHsManager.cpp +++ b/Source/CharacterPlugin/Private/Crowds/VHsManager.cpp @@ -15,7 +15,6 @@ void AVHsManager::BeginPlay() { Super::BeginPlay(); - /* Do NOT store all agents for the VHsManager as there might be several ones TArray<AActor*> Actors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AVirtualHuman::StaticClass(), Actors); @@ -82,20 +81,20 @@ void AVHsManager::Remove(AVirtualHuman* Agent) AllVHs.Remove(Agent); } -bool AVHsManager::HasAgent(AVirtualHuman * Agent) +bool AVHsManager::HasAgent(AVirtualHuman* Agent) { if (Agent == nullptr) { VH_ERROR("[AVHsManager::HasAgent] Attempted to find nullptr Agent") return false; } - return (AllVHs.Find(Agent) != INDEX_NONE); + return (AllVHs.Find(Agent) != INDEX_NONE); } void AVHsManager::SetCrowdAlgorithm(TSubclassOf<UVelocityPostProcessorComponent> NewCrowdAlgorithm) { CrowdAlgorithm = NewCrowdAlgorithm; - for(AVirtualHuman* VH : AllVHs) + for (AVirtualHuman* VH : AllVHs) { SetCrowdAlgorithmFor(VH); } @@ -104,13 +103,12 @@ void AVHsManager::SetCrowdAlgorithm(TSubclassOf<UVelocityPostProcessorComponent> TArray<AVirtualHuman*> AVHsManager::GetNeighbours(AVirtualHuman* VH, const float MaxDistance) { FVector VHLocation = VH->GetActorLocation(); - float MaxDistanceSq = MaxDistance*MaxDistance; + float MaxDistanceSq = MaxDistance * MaxDistance; return AllVHs.FilterByPredicate( - [VH, VHLocation, MaxDistanceSq](AActor* Agent) - { - return (VH != Agent) && (Agent != nullptr) && (FVector::DistSquared( - VHLocation, Agent->GetActorLocation()) < MaxDistanceSq); - }); + [VH, VHLocation, MaxDistanceSq](AActor* Agent) { + return (VH != Agent) && (Agent != nullptr) && + (FVector::DistSquared(VHLocation, Agent->GetActorLocation()) < MaxDistanceSq); + }); } @@ -121,17 +119,18 @@ TArray<AVirtualHuman*> AVHsManager::GetAllVHs() const void AVHsManager::SetCrowdAlgorithmFor(AVirtualHuman* VH) { - if(CrowdAlgorithm == nullptr) + if (CrowdAlgorithm == nullptr) { return; } TArray<UVelocityPostProcessorComponent*> OldComponents; VH->GetComponents(OldComponents); - for(UVelocityPostProcessorComponent* OldComponent : OldComponents){ + for (UVelocityPostProcessorComponent* OldComponent : OldComponents) + { OldComponent->DestroyComponent(); } UVelocityPostProcessorComponent* SpawnedComponent = NewObject<UVelocityPostProcessorComponent>(VH, CrowdAlgorithm); SpawnedComponent->RegisterComponent(); -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/Crowds/VelocityPostProcessorComponent.cpp b/Source/CharacterPlugin/Private/Crowds/VelocityPostProcessorComponent.cpp index a915caede6668171aa65ccd6397ce75b2ce3b51a..6690d0260a70f053a9c9c33504ef0faf47cdf2c1 100644 --- a/Source/CharacterPlugin/Private/Crowds/VelocityPostProcessorComponent.cpp +++ b/Source/CharacterPlugin/Private/Crowds/VelocityPostProcessorComponent.cpp @@ -19,4 +19,4 @@ void UVelocityPostProcessorComponent::PostProcessVelocity(float LastDeltaTime, F { Velocity = FVector::ZeroVector; VH_WARN("Velocity Post Processor not implemented as this is the base class.") -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroup.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroup.cpp index cc82f1cbb137f8b188b511160ec1460cf15dc894..d7d1a0dbd32ff07c846627cb823f080fb881af98 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroup.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroup.cpp @@ -47,7 +47,7 @@ ASocialGroup::ASocialGroup() // Called when the game starts or when spawned void ASocialGroup::BeginPlay() { - + Super::BeginPlay(); CollisionSphere->OnComponentBeginOverlap.AddDynamic(this, &ASocialGroup::OnSphereBeginOverlap); CollisionSphere->OnComponentEndOverlap.AddDynamic(this, &ASocialGroup::OnSphereEndOverlap); @@ -57,16 +57,16 @@ void ASocialGroup::BeginPlay() SocialGroupRandomStream = FRandomStream(TextKeyUtil::HashString(GetName())); VRPawn = Cast<ARWTHVRPawn>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0)); - if(!VRPawn) + if (!VRPawn) { VH_ERROR("[ASocialGroup::BeginPlay] The pawn is not a AVirtualRealityPawn, this method does not work!") } - - if(!bSpawnAsGroup) + + if (!bSpawnAsGroup) { GroupSize = AgentsInGroup.Num(); } - + if (GroupSize < 2) { // A Social Group should at least contain two agents @@ -77,20 +77,21 @@ void ASocialGroup::BeginPlay() { VH_WARN("[ASocialGroup::BeginPlay] Group size is larger than 10! Social Groups have only been tested to work with at most 10 agents. Proceed at own risk.\n") } - + //spawn specified amount of agents at start of the game, instead of adding agents manually if (bSpawnAsGroup) { GroupRadius = GetGroupRadius(GroupSize); AgentsInGroup = SpawnInGroupFormation(); StartRandomGazingTimer(2.0f); - } else // AgentsInGroup will be filled via the editor by the user + } + else // AgentsInGroup will be filled via the editor by the user { GroupRadius = GetGroupRadius(AgentsInGroup.Num()); StartRandomGazingTimer(2.0f); } // initialize all parameters - for(int i = 0; i < AgentsInGroup.Num(); i++) + for (int i = 0; i < AgentsInGroup.Num(); i++) { GetSocialGroupsComponent(AgentsInGroup[i])->InitializeParameters(this); auto MovementComp = AgentsInGroup[i]->FindComponentByClass<UCharacterMovementComponent>(); @@ -102,10 +103,9 @@ void ASocialGroup::BeginPlay() } } - // set Animation Montages used during group behavior WavingMontages = LoadAnimationMontages(); - if(WavingMontages.Num() < 1) + if (WavingMontages.Num() < 1) { VH_ERROR("[ASocialGroup::BeginPlay] Could not load waving animation.\n") return; @@ -115,9 +115,9 @@ void ASocialGroup::BeginPlay() //since all audio files are loaded for all agents since we don'T know who will speak it //so rather call it manually if you need that, better just set bStartDialogue (then the right things are preloaded) //PreloadDialogue(); - + CollisionSphere->SetSphereRadius(GroupRadius + 1.2 * GazeDistance); - if(bStartDialogue) + if (bStartDialogue) { StartDialogue(5.0f); } @@ -127,7 +127,7 @@ void ASocialGroup::BeginPlay() Gazing = NewObject<USG_Gazing>(); Leaving = NewObject<USG_Leaving>(); InGroup = NewObject<USG_InGroup>(); - + // add starting state of user (index 0) GroupStates.Add(Idle); } @@ -136,9 +136,9 @@ void ASocialGroup::BeginPlay() void ASocialGroup::Tick(float DeltaTime) { Super::Tick(DeltaTime); - + // if iterator is 0 we track the user, if the iterator is 1 or bigger we track all agents, which are inside the collision sphere - if(TrackedAgentIt == 0) + if (TrackedAgentIt == 0) { // if the TrackedAgentIt is 0 we track the player AgentPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0); @@ -153,10 +153,10 @@ void ASocialGroup::Tick(float DeltaTime) TrackedPawnLocation = UGameplayStatics::GetPlayerPawn(GetWorld(), 0)->GetActorLocation(); } } - else if(TrackedAgentIt >= 1) + else if (TrackedAgentIt >= 1) { - AgentPawn = Cast<APawn>(CloseAgents[TrackedAgentIt-1]); - if(!AgentPawn) + AgentPawn = Cast<APawn>(CloseAgents[TrackedAgentIt - 1]); + if (!AgentPawn) { VH_ERROR("[ASocialGroup::Tick] Cast to pawn failed\n") return; @@ -164,39 +164,38 @@ void ASocialGroup::Tick(float DeltaTime) bUser = false; TrackedPawnLocation = AgentPawn->GetActorLocation(); } - + GroupStates[TrackedAgentIt]->Tick(this); const FVector ToTrackedPawn = TrackedPawnLocation - GetActorLocation(); - + //********************************************************************* // state transitions //********************************************************************* - if (ToTrackedPawn.Size() < GroupRadius + GazeDistance) - { - GroupStates[TrackedAgentIt]->ToGazing(this); - } - - if (IsUserOrientedToGroup(ToGroupThreshold) && ToTrackedPawn.Size() < GroupRadius + JoinDistance) - { - if(!bPlayerIsInGroup && bUser) - { - GroupStates[TrackedAgentIt]->ToInGroup(this); - } - } - - if (ToTrackedPawn.Size() > GroupRadius + GazeDistance + GroupRadius / 3) - { - GroupStates[TrackedAgentIt]->ToIdle(this); - } - - if (!IsUserOrientedToGroup(ToGroupThreshold) && ToTrackedPawn.Size() > GroupRadius + StillStandingVariance) + if (ToTrackedPawn.Size() < GroupRadius + GazeDistance) + { + GroupStates[TrackedAgentIt]->ToGazing(this); + } + + if (IsUserOrientedToGroup(ToGroupThreshold) && ToTrackedPawn.Size() < GroupRadius + JoinDistance) + { + if (!bPlayerIsInGroup && bUser) { - GroupStates[TrackedAgentIt]->ToLeaving(this); + GroupStates[TrackedAgentIt]->ToInGroup(this); } - + } + + if (ToTrackedPawn.Size() > GroupRadius + GazeDistance + GroupRadius / 3) + { + GroupStates[TrackedAgentIt]->ToIdle(this); + } + + if (!IsUserOrientedToGroup(ToGroupThreshold) && ToTrackedPawn.Size() > GroupRadius + StillStandingVariance) + { + GroupStates[TrackedAgentIt]->ToLeaving(this); + } // when join agent function is called, this will be true - if(bAgentIsJoining) + if (bAgentIsJoining) { const FVector DistanceToGroup = GetActorLocation() - JoiningAgent->GetActorLocation(); if (DistanceToGroup.Size() < GroupRadius + JoinDistance) @@ -206,7 +205,7 @@ void ASocialGroup::Tick(float DeltaTime) JoiningAgent->GetCharacterMovement()->bOrientRotationToMovement = false; GroupRadius = GetGroupRadius(AgentsInGroup.Num()); GetSocialGroupsComponent(JoiningAgent)->InitializeParameters(this); - if(bStartDialogue) + if (bStartDialogue) { RestartDialogue(3.0f); } @@ -216,7 +215,7 @@ void ASocialGroup::Tick(float DeltaTime) //iterate over all agents, that are in the collision sphere around the group TrackedAgentIt++; - if (TrackedAgentIt >= CloseAgents.Num() +1) //+1 as TrackedAgentIt=0 is the player + if (TrackedAgentIt >= CloseAgents.Num() + 1) //+1 as TrackedAgentIt=0 is the player { TrackedAgentIt = 0; } @@ -238,7 +237,7 @@ bool ASocialGroup::IsUserOrientedToGroup(float Threshold) UserForwardXY.Normalize(); UserToGroupCenterXY.Normalize(); - + float Angle = FMath::Abs(FVector2D::DotProduct(UserForwardXY, UserToGroupCenterXY)); Angle = FMath::Acos(Angle); Angle = FMath::RadiansToDegrees(Angle); @@ -257,7 +256,7 @@ float ASocialGroup::GetGroupRadius(int NumberOfAgents) const { if (bPlayerIsInGroup) { - NumberOfAgents ++; + NumberOfAgents++; } // arc measure: b = alpha/360 * 2 * pi * r => r = b * 360 / (alpha * 2 * pi) @@ -272,13 +271,13 @@ float ASocialGroup::GetGroupRadius(int NumberOfAgents) const TArray<FVector> ASocialGroup::GetCirclePositions(int NumberOfAgents) { GroupRadius = GetGroupRadius(NumberOfAgents); - if(bPlayerIsInGroup) + if (bPlayerIsInGroup) { NumberOfAgents++; } float Alpha = 360.0 / NumberOfAgents; TArray<FVector> Positions; - + for (int i = 0; i < NumberOfAgents; i++) { const float RandomDeviation = SocialGroupRandomStream.FRandRange(-5.0f, 5.0f); @@ -297,19 +296,18 @@ void ASocialGroup::SortByDistanceToActor(FVector ActorLocation) { FVector ActorPos = ActorLocation; // sort the array according to the distance to the ActorLocation - AgentsInGroup.Sort([ActorPos](AVirtualHuman& vh1, AVirtualHuman& vh2) - { - FVector d1 = ActorPos - vh1.GetActorLocation(); - FVector d2 = ActorPos - vh2.GetActorLocation(); + AgentsInGroup.Sort([ActorPos](AVirtualHuman& vh1, AVirtualHuman& vh2) { + FVector d1 = ActorPos - vh1.GetActorLocation(); + FVector d2 = ActorPos - vh2.GetActorLocation(); - return d1.Size() < d2.Size(); + return d1.Size() < d2.Size(); }); } // returns the speaker of the group, or nulptr if there is no speaker AActor* ASocialGroup::GetSpeaker() { - for(int i = 0; i < AgentsInGroup.Num(); i++) + for (int i = 0; i < AgentsInGroup.Num(); i++) { auto VH = AgentsInGroup[i]; auto SGComp = GetSocialGroupsComponent(VH); @@ -325,7 +323,7 @@ AActor* ASocialGroup::GetSpeaker() TArray<AVirtualHuman*> ASocialGroup::SpawnInGroupFormation() { TArray<AVirtualHuman*> Agents; - if (VHTypes.Num()<=0) + if (VHTypes.Num() <= 0) { VH_ERROR("[ASocialGroup::SpawnInGroupFormation] Could not spawn agents. Please specify a subclass of virtual human, that should be spawned.\n"); return Agents; @@ -336,7 +334,7 @@ TArray<AVirtualHuman*> ASocialGroup::SpawnInGroupFormation() { DestroyAgent(); } - + TArray<FVector> CirclePositions = GetCirclePositions(GroupSize); for (int i = 0; i < GroupSize; i++) { @@ -347,25 +345,25 @@ TArray<AVirtualHuman*> ASocialGroup::SpawnInGroupFormation() //adjust z value of spawn location. Otherwise VAs are stuck in ground. SpawnLocation.Z = SpawnLocation.Z + 80.0f; FRotator Rotation = UKismetMathLibrary::FindLookAtRotation(CirclePositions[i], GetActorLocation()); - AVirtualHuman* VH = GetWorld()->SpawnActor<AVirtualHuman>(VHType, SpawnLocation, FRotator(0,Rotation.Yaw,0), SpawnParams); + AVirtualHuman* VH = GetWorld()->SpawnActor<AVirtualHuman>(VHType, SpawnLocation, FRotator(0, Rotation.Yaw, 0), SpawnParams); // check if the agent has all the necessary components - + auto SGComp = GetSocialGroupsComponent(VH); - if(!SGComp) + if (!SGComp) { continue; } - if(!SGComp->InitializeParameters(this)) + if (!SGComp->InitializeParameters(this)) { continue; } - + // Rotate agent towards the center auto GC = VH->FindComponentByClass<UVHGazing>(); GC->StopGazing(); - + auto MovementComp = VH->FindComponentByClass<UCharacterMovementComponent>(); if (MovementComp) { @@ -384,7 +382,8 @@ TArray<AVirtualHuman*> ASocialGroup::SpawnInGroupFormation() bool ASocialGroup::StartDialogue(float InitialDelay) { // if bStartDialogue was not true the AudioComponents of the social group need to be initialized since that only happened for the social groups where the dialogue was started before. - if (bStartDialogue == false) { + if (bStartDialogue == false) + { bStartDialogue = true; for (int i = 0; i < AgentsInGroup.Num(); i++) { @@ -394,7 +393,7 @@ bool ASocialGroup::StartDialogue(float InitialDelay) } } SetupDialogue(); - GetWorld()->GetTimerManager().SetTimer(SpeakerTimerHandle, this, &ASocialGroup::SetSpeaker, InitialDelay,false); + GetWorld()->GetTimerManager().SetTimer(SpeakerTimerHandle, this, &ASocialGroup::SetSpeaker, InitialDelay, false); return true; } @@ -417,18 +416,18 @@ bool ASocialGroup::SetupDialogue() NumberOfAgentsInConversation = Dialogue.Num(); } - if(AgentsInGroup.Num() < NumberOfAgentsInConversation) + if (AgentsInGroup.Num() < NumberOfAgentsInConversation) { VH_WARN("There are only %d agents in the group. Cannot set up a conversation with %d agents\n", AgentsInGroup.Num(), NumberOfAgentsInConversation); return false; } - + TArray<AVirtualHuman*> Agents = ShuffleArray(AgentsInGroup); int DiaIt = 0; // assign NumberOfAgentsInConversation dialogues to agents - for(int AgentIt = 0; AgentIt < Agents.Num() -1;) + for (int AgentIt = 0; AgentIt < Agents.Num() - 1;) { - if(DiaIt < NumberOfAgentsInConversation) + if (DiaIt < NumberOfAgentsInConversation) { if (Agents[AgentIt]->GetGender() == Dialogue[DiaIt].Gender) { @@ -444,18 +443,19 @@ bool ASocialGroup::SetupDialogue() { AgentIt++; } - } else + } + else { // end for loop AgentIt = Agents.Num() - 1; } } - if(AgentsInConversation.Num() < NumberOfAgentsInConversation) + if (AgentsInConversation.Num() < NumberOfAgentsInConversation) { VH_WARN("Could not match all dialogs to agents corretly. Check if the gender of the agents matches the gender of the dialog"); // match unmatched dialogue to other agents - while(AgentsInConversation.Num() < NumberOfAgentsInConversation) + while (AgentsInConversation.Num() < NumberOfAgentsInConversation) { FAgentDialogueUtterance NewDialog; NewDialog.VH = Agents[0]; @@ -468,7 +468,7 @@ bool ASocialGroup::SetupDialogue() // it might be the case, that there are multiple dialogues for the same agent // now we need to assign the other Dialogues, to the agents, that are in dialogue - for(int z = NumberOfAgentsInConversation; z < Dialogue.Num(); z++) + for (int z = NumberOfAgentsInConversation; z < Dialogue.Num(); z++) { FAgentDialogueUtterance NewDialogue; NewDialogue.VH = AgentsInConversation[z % NumberOfAgentsInConversation].VH; @@ -477,7 +477,7 @@ bool ASocialGroup::SetupDialogue() } // PreLoad animation and audio to save performance - for(auto Conv : AgentsInConversation) + for (auto Conv : AgentsInConversation) { GetSpeechComponent(Conv.VH)->PreloadUtterance(Conv.Utterance); } @@ -490,9 +490,9 @@ void ASocialGroup::PreloadDialogue() //but since we don't know who is speaking what we preload everything for everyone //this can be very intense, so use with care - for(AVirtualHuman* Agent : AgentsInGroup) + for (AVirtualHuman* Agent : AgentsInGroup) { - for(const FDialogueUtterance &Utterance : Dialogue) + for (const FDialogueUtterance& Utterance : Dialogue) { GetSpeechComponent(Agent)->PreloadUtterance(Utterance); } @@ -522,7 +522,7 @@ void ASocialGroup::PauseDialogue(float Duration) GetSpeechComponent(VH)->PauseDialogue(); } } - + // Restart dialogue after given Duration GetWorld()->GetTimerManager().SetTimer(SpeakerTimerHandle, this, &ASocialGroup::SetSpeaker, Duration, false); } @@ -535,12 +535,13 @@ void ASocialGroup::ClearSpeakerTimer() void ASocialGroup::SetSpeaker() { - if(DialogueIterator >= Dialogue.Num()) + if (DialogueIterator >= Dialogue.Num()) { - if(bLoopDialogue) + if (bLoopDialogue) { DialogueIterator = 0; - } else + } + else { return; } @@ -549,17 +550,18 @@ void ASocialGroup::SetSpeaker() AVirtualHuman* VH = AgentsInConversation[DialogueIterator].VH; // it might be the case, that an agent, that was part of the conversation, has left the group at some point - if(!AgentsInGroup.Contains(VH)) + if (!AgentsInGroup.Contains(VH)) { RestartDialogue(2.0f); return; } UVHSocialGroups* SGComp = GetSocialGroupsComponent(VH); SGComp->SetIsSpeaker(true); - if(Dialogue.IsValidIndex(DialogueIterator)) + if (Dialogue.IsValidIndex(DialogueIterator)) { GetSpeechComponent(VH)->PlayDialogue(CurrentDialogue, 1.5f); - } else + } + else { VH_WARN("[ASocialGroup::SetSpeaker] No entry found for Dialogues Index: %d\n", DialogueIterator); } @@ -583,7 +585,7 @@ void ASocialGroup::StartRandomGazing() UVHSocialGroups* ASocialGroup::GetSocialGroupsComponent(AVirtualHuman* VH) const { const auto SG = VH->FindComponentByClass<UVHSocialGroups>(); - if(!SG) + if (!SG) { VH_WARN("[ASocialGroup::GetSocialGroupsComponent] Virtual Human has no valid SocialGroup component\n"); } @@ -616,17 +618,16 @@ void ASocialGroup::SortByAngleToPlayer() FVector PlayerPos = TrackedPawnLocation; FVector PlayerForward = VRPawn->GetActorForwardVector(); // sort Agents in Group according to angle to the user - AgentsInGroup.Sort([PlayerForward](AVirtualHuman& vh1, AVirtualHuman& vh2) - { - // Check if this agent is in front of the player - FVector PlayerToVA1 = vh1.GetActorLocation() - PlayerForward; - float Dot1 = FVector::DotProduct(PlayerForward, PlayerToVA1); + AgentsInGroup.Sort([PlayerForward](AVirtualHuman& vh1, AVirtualHuman& vh2) { + // Check if this agent is in front of the player + FVector PlayerToVA1 = vh1.GetActorLocation() - PlayerForward; + float Dot1 = FVector::DotProduct(PlayerForward, PlayerToVA1); - FVector PlayerToVA2 = vh2.GetActorLocation() - PlayerForward; - float Dot2 = FVector::DotProduct(PlayerForward, PlayerToVA2); + FVector PlayerToVA2 = vh2.GetActorLocation() - PlayerForward; + float Dot2 = FVector::DotProduct(PlayerForward, PlayerToVA2); - return Dot1 > Dot2; - }); + return Dot1 > Dot2; + }); } TArray<AVirtualHuman*> ASocialGroup::ShuffleArray(TArray<AVirtualHuman*> Agents) @@ -648,7 +649,7 @@ TArray<AVirtualHuman*> ASocialGroup::ShuffleArray(TArray<AVirtualHuman*> Agents) void ASocialGroup::LeaveGroup(AVirtualHuman* VH) { - if(!AgentsInGroup.Contains(VH)) + if (!AgentsInGroup.Contains(VH)) { VH_WARN("[ASocialGroup::LeaveGroup] Agent was not part of the group\n"); return; @@ -661,7 +662,7 @@ void ASocialGroup::LeaveGroup(AVirtualHuman* VH) auto SGComp = GetSocialGroupsComponent(VH); SGComp->EndGazing(); SGComp->SetSocialGroup(nullptr); - if(bStartDialogue) + if (bStartDialogue) { RestartDialogue(2.0f); } @@ -676,7 +677,7 @@ void ASocialGroup::JoinGroup(AVirtualHuman* VH) } JoiningAgent = VH; bAgentIsJoining = true; - GetSocialGroupsComponent(VH)->VHMoveToLocation(GetActorLocation(),100); + GetSocialGroupsComponent(VH)->VHMoveToLocation(GetActorLocation(), 100); // in OnTick we check if the agent is close to the group and then integrate him into the group } @@ -684,21 +685,21 @@ void ASocialGroup::JoinGroup(AVirtualHuman* VH) void ASocialGroup::OnSphereBeginOverlap(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { AVirtualHuman* CloseAgent = Cast<AVirtualHuman>(OtherActor); - if(!CloseAgent) + if (!CloseAgent) { return; } - if(!AgentsInGroup.Contains(CloseAgent)) + if (!AgentsInGroup.Contains(CloseAgent)) { CloseAgents.AddUnique(CloseAgent); - GroupStates.Add(Idle);// starting state + GroupStates.Add(Idle); // starting state } } void ASocialGroup::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) { AVirtualHuman* CloseAgent = Cast<AVirtualHuman>(OtherActor); - if(!CloseAgent) + if (!CloseAgent) { return; } @@ -731,7 +732,7 @@ TArray<UAnimMontage*> ASocialGroup::LoadAnimationMontages() const { Path = "/CharacterPlugin/Animations/Waving/MH"; } - + if (!FPaths::ValidatePath(Path)) { VH_WARN("[ASocialGroup::LoadAnimationMontages] Path: %s is not valid\n", *Path) @@ -753,5 +754,4 @@ TArray<UAnimMontage*> ASocialGroup::LoadAnimationMontages() const } } return Montages; -} - +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupState.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupState.cpp index b43eb9b871773c8000c8d12fcf9874d12166d5d8..dfc1584e8fcc26f8a335f70ff9ffc788b38f8997 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupState.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupState.cpp @@ -5,22 +5,12 @@ // Add default functionality here for any ISocialGroupState functions that are not pure virtual. -void ISocialGroupState::Tick(ASocialGroup* SG) -{ -} +void ISocialGroupState::Tick(ASocialGroup* SG) {} -void ISocialGroupState::ToIdle(ASocialGroup* SG) -{ -} +void ISocialGroupState::ToIdle(ASocialGroup* SG) {} -void ISocialGroupState::ToGazing(ASocialGroup* SG) -{ -} +void ISocialGroupState::ToGazing(ASocialGroup* SG) {} -void ISocialGroupState::ToInGroup(ASocialGroup* SG) -{ -} +void ISocialGroupState::ToInGroup(ASocialGroup* SG) {} -void ISocialGroupState::ToLeaving(ASocialGroup* SG) -{ -} +void ISocialGroupState::ToLeaving(ASocialGroup* SG) {} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Gazing.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Gazing.cpp index bca2bb9532b46500a354e39762ab8f942a8b2f87..60cbdc91c7e065f5261000c136dc5e19a6b7645a 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Gazing.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Gazing.cpp @@ -18,10 +18,11 @@ void USG_Gazing::Tick(ASocialGroup* SG) { UVHGazing* GazingComponent = SG->AgentsInGroup[i]->FindComponentByClass<UVHGazing>(); // in case we track the user, we gaze to the users head - if(SG->bUser) + if (SG->bUser) { GazingComponent->GazeToUser(); - } else + } + else { // we gaze to an agent GazingComponent->GazeToActor(SG->AgentPawn, FVector(0, 0, SG->AgentPawn->BaseEyeHeight)); @@ -57,7 +58,7 @@ void USG_Gazing::ToInGroup(ASocialGroup* SG) // make the agent opposite to the user play a waving animation SG->SortByAngleToPlayer(); - SG->AgentsInGroup[0]->PlayAnimMontage(SG->WavingMontages[SGGazingRandomStream.RandRange(0,SG->WavingMontages.Num()-1)]); + SG->AgentsInGroup[0]->PlayAnimMontage(SG->WavingMontages[SGGazingRandomStream.RandRange(0, SG->WavingMontages.Num() - 1)]); //UniLog.Log("InGroup", "VHDebug"); SG->ChangeState(SG->InGroup); } @@ -95,4 +96,4 @@ void USG_Gazing::LookAtUserOnJoin(ASocialGroup* SG) GazingComponent->GazeToActor(SG->AgentPawn, FVector(0, 0, SG->AgentPawn->BaseEyeHeight)); } } -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Idle.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Idle.cpp index c74da15d34483555dc83ff1e9928bfbd3d4e8a8a..cd57fe9ff7641c6fa88c7d4af53d18253c5dfcb5 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Idle.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Idle.cpp @@ -18,4 +18,4 @@ void USG_Idle::ToGazing(ASocialGroup* SG) // change to gazing SG->ChangeState(SG->Gazing); } -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_InGroup.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_InGroup.cpp index 6c803534b5bab28a21b9529074d908f98c1e7fa6..579417354939ef18e02c3f88480ca56610e271c5 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_InGroup.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_InGroup.cpp @@ -16,4 +16,4 @@ void USG_InGroup::ToLeaving(ASocialGroup* SG) SG->GroupRadius = SG->GetGroupRadius(SG->AgentsInGroup.Num()); //UniLog.Log("Leaving", "VHDebug"); SG->ChangeState(SG->Leaving); -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Leaving.cpp b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Leaving.cpp index e135d5498ce7f787f1b736368960112a861f0b43..8eb66803f44214405a64d4ef08bcd71b1f5fcad4 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Leaving.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/SocialGroupStates/SG_Leaving.cpp @@ -10,4 +10,4 @@ void USG_Leaving::ToIdle(ASocialGroup* SG) { //UniLog.Log("Idle", "VHDebug"); SG->ChangeState(SG->Idle); -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/SocialGroups/VHSocialGroups.cpp b/Source/CharacterPlugin/Private/SocialGroups/VHSocialGroups.cpp index 495b532cc0f2bc1000b9be1a92c2cd40f561e8c2..43c9fe9fedb3f1e732e64d82b728db80a6b81401 100644 --- a/Source/CharacterPlugin/Private/SocialGroups/VHSocialGroups.cpp +++ b/Source/CharacterPlugin/Private/SocialGroups/VHSocialGroups.cpp @@ -29,7 +29,7 @@ UVHSocialGroups::UVHSocialGroups() void UVHSocialGroups::BeginPlay() { Super::BeginPlay(); - if(!Init()) + if (!Init()) { return; } @@ -38,13 +38,14 @@ void UVHSocialGroups::BeginPlay() SocialGroupsRandomStream = FRandomStream(TextKeyUtil::HashString(*GetOwner()->GetName())); GazeState = GazeAtSpeaker; - + } + // will be called by the social group once VH has been spawned bool UVHSocialGroups::InitializeParameters(ASocialGroup* SetSocialGroup) { SocialGroup = SetSocialGroup; - if(!SocialGroup) + if (!SocialGroup) { VH_ERROR("[VHSocialGroups::InitializeParameters] Social Group is not valid\n"); return false; @@ -55,10 +56,10 @@ bool UVHSocialGroups::InitializeParameters(ASocialGroup* SetSocialGroup) VH_ERROR("[VHSocialGroups::InitializeParameters]: Virtual Human has no Gazing Component\n") return false; } - if(SocialGroup->bStartDialogue) + if (SocialGroup->bStartDialogue) { AudioComp = GetOwner()->FindComponentByClass<UVAAudiofileSourceComponent>(); - if(!AudioComp) + if (!AudioComp) { VH_ERROR("[VHSocialGroups::InitializeParameters]: Virtual Human has no Audiofile Source Component. If the Social Group should not have Dialogue, please disable the \"Start Dialogue\" flag.\n") return false; @@ -86,28 +87,29 @@ bool UVHSocialGroups::InitializeParameters(ASocialGroup* SetSocialGroup) void UVHSocialGroups::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - if(bIsSpeaker) + if (bIsSpeaker) { // if audio is playing we CAN finish if (AudioComp->GetAudiofileSignalSource()->GetPlayActionEnum() == EPlayAction::Play) { bAudioCanFinish = true; - // if audio is not playing anymore, but was playing before - } else if(bAudioCanFinish) + // if audio is not playing anymore, but was playing before + } + else if (bAudioCanFinish) { OnAudioFinished(); bAudioCanFinish = false; } } - if(SocialGroup) + if (SocialGroup) { // calculate force to standing position in the group FVector Movement = GetProximityForce() + GetCircleForce(); - + float Angle = FMath::Abs(FVector::DotProduct(GetProximityForce(), GetCircleForce())); // to increase stability, do not move if forces are very small - if(Movement.Size() > 2.0f) + if (Movement.Size() > 2.0f) { Movement.Normalize(); VHPawn->AddMovementInput(Movement, 0.3f); @@ -132,8 +134,8 @@ void UVHSocialGroups::TickComponent(float DeltaTime, ELevelTick TickType, FActor FVector UVHSocialGroups::GetProximityForce() { FVector Force = FVector::ZeroVector; - - for(int i = 0; i < SocialGroup->AgentsInGroup.Num(); i++) + + for (int i = 0; i < SocialGroup->AgentsInGroup.Num(); i++) { FVector CurrentAgent = VHPawn->GetActorLocation(); FVector OtherAgent = SocialGroup->AgentsInGroup[i]->GetActorLocation(); @@ -145,15 +147,15 @@ FVector UVHSocialGroups::GetProximityForce() Distance.Normalize(); Force += Distance * ToDesiredDistance; } - + } - if(SocialGroup->bPlayerIsInGroup) + if (SocialGroup->bPlayerIsInGroup) { FVector CurrentAgent = VHPawn->GetActorLocation(); FVector OtherAgent = SocialGroup->VRPawn->HeadCameraComponent->GetComponentLocation(); FVector Distance = OtherAgent - CurrentAgent; - if (Distance.Size() < SocialGroup->ConversationDistance && Distance.Size()>0) + if (Distance.Size() < SocialGroup->ConversationDistance && Distance.Size() > 0) { float ToDesiredDistance = SocialGroup->ConversationDistance - Distance.Size(); Distance.Normalize(); @@ -169,20 +171,20 @@ FVector UVHSocialGroups::GetCircleForce() { FVector2D GroupCenter = FVector2D(SocialGroup->GetActorLocation().X, SocialGroup->GetActorLocation().Y); FVector2D Agent = FVector2D(VHPawn->GetActorLocation().X, VHPawn->GetActorLocation().Y); - + FVector2D Direction = GroupCenter - Agent; float DesiredLength = Direction.Size() - SocialGroup->GroupRadius; Direction.Normalize(); - return FVector(Direction,0) * DesiredLength; + return FVector(Direction, 0) * DesiredLength; } // if the audio has finished, start the next dialogue void UVHSocialGroups::OnAudioFinished() { bIsSpeaker = false; - + // do not call next dialogue if the audio is only paused - if(AudioComp->GetAudiofileSignalSource()->GetPlayActionEnum() != EPlayAction::Pause) + if (AudioComp->GetAudiofileSignalSource()->GetPlayActionEnum() != EPlayAction::Pause) { SocialGroup->NextDialogue(); } @@ -196,7 +198,7 @@ UCharacterMovementComponent* UVHSocialGroups::GetCharacterMovementComponent() VH_ERROR("[VHSocialGroups]: Owner can not be cast to Pawn\n"); return nullptr; } - + return Cast<UCharacterMovementComponent>(VHPawn->GetMovementComponent()); } @@ -204,7 +206,7 @@ void UVHSocialGroups::VHMoveToLocation(FVector Location, float Speed) { GetCharacterMovementComponent()->MaxWalkSpeed = Speed; AIController = Cast<AVirtualHumanAIController>(VHPawn->GetController()); - CurrentRequestID = AIController->MoveToLocation(Location, 2.0f,false); + CurrentRequestID = AIController->MoveToLocation(Location, 2.0f, false); } void UVHSocialGroups::SetGazingTimer() @@ -213,14 +215,14 @@ void UVHSocialGroups::SetGazingTimer() switch (GazeState) { - case GazeAtSpeaker: - TimerInterval = SocialGroupsRandomStream.FRandRange(3.0f, 10.0f); - break; - case GazeAtRandom: - TimerInterval = SocialGroupsRandomStream.FRandRange(3.5f, 4.5f); - break; - default: - break; + case GazeAtSpeaker: + TimerInterval = SocialGroupsRandomStream.FRandRange(3.0f, 10.0f); + break; + case GazeAtRandom: + TimerInterval = SocialGroupsRandomStream.FRandRange(3.5f, 4.5f); + break; + default: + break; } GetWorld()->GetTimerManager().SetTimer(GazingTimerHandle, this, &UVHSocialGroups::RandomGazing, TimerInterval, false); @@ -240,52 +242,55 @@ void UVHSocialGroups::RandomGazing() const FVector Offset = FVector(0, 0, AVirtualHumanPtr->BaseEyeHeight); switch (GazeState) { - case GazeAtSpeaker: - Speaker = SocialGroup->GetSpeaker(); - - // make sure speaker is valid, and we are not the speaker - if(IsValid(Speaker) && !bIsSpeaker) - { - GazingComp->GazeToActor(Speaker,Offset); - } else - { - // if we are speaking, or if there is currently no speaker, gaze at random agent - RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); + case GazeAtSpeaker: + Speaker = SocialGroup->GetSpeaker(); - while(SocialGroup->AgentsInGroup[RandomIndex] == AVirtualHumanPtr) + // make sure speaker is valid, and we are not the speaker + if (IsValid(Speaker) && !bIsSpeaker) { - RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); + GazingComp->GazeToActor(Speaker, Offset); } - GazingComp->GazeToActor(SocialGroup->AgentsInGroup[RandomIndex],Offset); - } - GazeState = GazeAtRandom; - break; - case GazeAtRandom: + else + { + // if we are speaking, or if there is currently no speaker, gaze at random agent + RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); - if(SocialGroup->bPlayerIsInGroup) - { - RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num()); - } else - { - RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num()-1); - } + while (SocialGroup->AgentsInGroup[RandomIndex] == AVirtualHumanPtr) + { + RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); + } + GazingComp->GazeToActor(SocialGroup->AgentsInGroup[RandomIndex], Offset); + } + GazeState = GazeAtRandom; + break; + case GazeAtRandom: - if(RandomIndex == SocialGroup->AgentsInGroup.Num()) - { - GazingComp->GazeToUser(); - } else - { - while (SocialGroup->AgentsInGroup[RandomIndex] == AVirtualHumanPtr) + if (SocialGroup->bPlayerIsInGroup) + { + RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num()); + } + else { RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); } - GazingComp->GazeToActor(SocialGroup->AgentsInGroup[RandomIndex], Offset); - } - GazeState = GazeAtSpeaker; - break; - default: - GazingComp->StopGazing(); - break; + + if (RandomIndex == SocialGroup->AgentsInGroup.Num()) + { + GazingComp->GazeToUser(); + } + else + { + while (SocialGroup->AgentsInGroup[RandomIndex] == AVirtualHumanPtr) + { + RandomIndex = SocialGroupsRandomStream.RandRange(0, SocialGroup->AgentsInGroup.Num() - 1); + } + GazingComp->GazeToActor(SocialGroup->AgentsInGroup[RandomIndex], Offset); + } + GazeState = GazeAtSpeaker; + break; + default: + GazingComp->StopGazing(); + break; } // loop back to set the gazing timer @@ -294,7 +299,7 @@ void UVHSocialGroups::RandomGazing() void UVHSocialGroups::LeaveGroup() { - if(!SocialGroup) + if (!SocialGroup) { VH_WARN("[VHSocialGroups::LeaveGroup] SocialGroup is not valid when calling LeaveGroup()\n"); return; @@ -304,7 +309,7 @@ void UVHSocialGroups::LeaveGroup() void UVHSocialGroups::JoinGroup(ASocialGroup* SG) { - if(!SG) + if (!SG) { VH_ERROR("[VHSocialGroups::JoinGroup] SocialGroup is not valid when calling JoinGroup\n"); return; @@ -325,6 +330,7 @@ void UVHSocialGroups::StartGazeToUserTimer() } GetWorld()->GetTimerManager().SetTimer(GazeToUserTimer, this, &UVHSocialGroups::GazeToUser, TimerInterval, false); } + void UVHSocialGroups::ClearGazeToUserTimer() { bGazeToUser = false; @@ -344,7 +350,7 @@ void UVHSocialGroups::GazeToUser() bool UVHSocialGroups::Init() { AVirtualHumanPtr = Cast<AVirtualHuman>(GetOwner()); - if(!AVirtualHumanPtr) + if (!AVirtualHumanPtr) { VH_ERROR("[VHSocialGroups::Init] Cannot cast Owner to Virtual Human\n") return false; diff --git a/Source/CharacterPlugin/Private/VHAnimInstance.cpp b/Source/CharacterPlugin/Private/VHAnimInstance.cpp index b5d25e60938551651cbc2dc156f6735cf3bde0b7..bc355e4baa134f52ce438a29257f07c4785b2e43 100644 --- a/Source/CharacterPlugin/Private/VHAnimInstance.cpp +++ b/Source/CharacterPlugin/Private/VHAnimInstance.cpp @@ -3,6 +3,4 @@ #include "VHAnimInstance.h" UVHAnimInstance::UVHAnimInstance(const FObjectInitializer& ObjectInitializer) - : Super(ObjectInitializer) -{ -} + : Super(ObjectInitializer) {} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/VHListenerBackchannels.cpp b/Source/CharacterPlugin/Private/VHListenerBackchannels.cpp index e068dd950049c13000b9ab88031097344c328e5c..7080e67da097bf7baf4142bc4a8c0563fa67695a 100644 --- a/Source/CharacterPlugin/Private/VHListenerBackchannels.cpp +++ b/Source/CharacterPlugin/Private/VHListenerBackchannels.cpp @@ -19,11 +19,13 @@ void UVHListenerBackchannels::BeginPlay() { Super::BeginPlay(); AVirtualHuman* Owner = Cast<AVirtualHuman>(GetOwner()); - if (Owner != nullptr) { + if (Owner != nullptr) + { AnimInstance = Owner->GetBodyAnimInstance(); } - - if (!AnimInstance) { + + if (!AnimInstance) + { VH_ERROR("[UVHListenerBackchannels::BeginPlay] No AnimInstance at BeginPlay\n"); } RandomStream = FRandomStream(TextKeyUtil::HashString(*GetOwner()->GetName())); @@ -34,19 +36,19 @@ void UVHListenerBackchannels::TickComponent(float DeltaTime, ELevelTick TickType { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - if(bNodding) + if (bNodding) { NoddingTime += DeltaTime; - if(NoddingTime>ActualNodLength) + if (NoddingTime > ActualNodLength) { bNodding = false; } else { //formula from work by Klara Tyroller extended by some randomness and possible prolongment - float HeadPitch = - cos((NoddingTime * 2 * PI) / ActualNodDuration) * ActualNodAmplitude + ActualNodAmplitude; + float HeadPitch = -cos((NoddingTime * 2 * PI) / ActualNodDuration) * ActualNodAmplitude + ActualNodAmplitude; //decrease over time, e.g., if more than one nod is played - HeadPitch *= (ActualNodLength - NoddingTime) / ActualNodLength; + HeadPitch *= (ActualNodLength - NoddingTime) / ActualNodLength; AnimInstance->SkelControl_Head.Roll = HeadPitch; //is actually the pitch } @@ -55,14 +57,14 @@ void UVHListenerBackchannels::TickComponent(float DeltaTime, ELevelTick TickType void UVHListenerBackchannels::StartNod() { - if(bNodding) + if (bNodding) { return; } ActualNodAmplitude = RandomStream.FRandRange(0.5f * NodAmplitude, 1.5f * NodAmplitude); ActualNodDuration = RandomStream.FRandRange(0.5f * NodDuration, 1.5f * NodDuration); - if(ActualNodDuration < NodDuration) + if (ActualNodDuration < NodDuration) { //play one to three nods ActualNodLength = RandomStream.FRandRange(1.5f, 3.0f) * ActualNodDuration; @@ -74,5 +76,4 @@ void UVHListenerBackchannels::StartNod() bNodding = true; NoddingTime = 0.0f; -} - +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/VHMovement.cpp b/Source/CharacterPlugin/Private/VHMovement.cpp index 9e667b0bbe59c73f83cd87501105fb5db77c1557..c3a17f4ab5bcdb5f79bc393851ae29c12cdce7da 100644 --- a/Source/CharacterPlugin/Private/VHMovement.cpp +++ b/Source/CharacterPlugin/Private/VHMovement.cpp @@ -62,7 +62,6 @@ void UVHMovement::BeginPlay() LeftFootSocket = AVirtualHumanPtr->GetBoneNames().foot_socket_l; AnimationInstance = AVirtualHumanPtr->GetBodyAnimInstance(); - //set child Parameters int i = 1; for (TPair<AVirtualHuman*, float>& child : ChildVH) @@ -105,7 +104,8 @@ void UVHMovement::TickComponent(float DeltaTime, ELevelTick TickType, FActorComp void UVHMovement::CalculateIK(const float DeltaTime) { - if (!AnimationInstance) return; + if (!AnimationInstance) + return; // Calculate IKOffset for Foot alignment const FVector MeshLocation = AVirtualHumanPtr->GetBodyMesh()->GetComponentLocation(); @@ -159,8 +159,8 @@ void UVHMovement::CalculateIK(const float DeltaTime) // the Socket is at the front of the foot // the bone we rotate around is at the back of the foot const BoneNames& bones = AVirtualHumanPtr->GetBoneNames(); - FVector footVector = AVirtualHumanPtr->GetBodyMesh()->GetBoneLocation(bones.foot_r) - AVirtualHumanPtr-> - GetBodyMesh()->GetSocketLocation(RightFootSocket); + FVector footVector = AVirtualHumanPtr->GetBodyMesh()->GetBoneLocation(bones.foot_r) + - AVirtualHumanPtr->GetBodyMesh()->GetSocketLocation(RightFootSocket); float footLength = footVector.Size(); // the length of the shoe float rotationErrorHeightAdjustment = tanf(footRotationAngleRAD) * footLength; rotationErrorHeightAdjustment = FMath::Clamp(rotationErrorHeightAdjustment, 0.0f, footLength); // safety clamp @@ -170,7 +170,7 @@ void UVHMovement::CalculateIK(const float DeltaTime) if (bWalkingUp) { IKFootRotationAngle = FMath::FInterpTo(IKFootRotationAngle, -FMath::RadiansToDegrees(footRotationAngleRAD), - DeltaTime, IKInterpSpeed); + DeltaTime, IKInterpSpeed); IKOffsetRight -= rotationErrorHeightAdjustment; IKOffsetLeft -= rotationErrorHeightAdjustment; @@ -178,7 +178,7 @@ void UVHMovement::CalculateIK(const float DeltaTime) else { IKFootRotationAngle = FMath::FInterpTo(IKFootRotationAngle, FMath::RadiansToDegrees(footRotationAngleRAD), - DeltaTime, IKInterpSpeed); + DeltaTime, IKInterpSpeed); IKOffsetRight += rotationErrorHeightAdjustment; IKOffsetLeft += rotationErrorHeightAdjustment; } @@ -231,7 +231,7 @@ void UVHMovement::MoveToWaypoint() // if we are at the last waypoint and it defines destroying agent, do so if (Waypoints.Num() != 0 && CurrentWaypointIterator == Waypoints.Num() && Waypoints[CurrentWaypointIterator - 1]-> - GetLastWaypointCommand() == EOnWaypointReach::Destroy) + GetLastWaypointCommand() == EOnWaypointReach::Destroy) { VirtualHumanAIController->DestroyAgent(); } @@ -252,9 +252,8 @@ void UVHMovement::MoveToWaypoint() return; } - auto Path = NavSys->FindPathToActorSynchronously(GetWorld(), AVirtualHumanPawn->GetActorLocation(), - CurrentWaypoint); + CurrentWaypoint); FAIMoveRequest Request = FAIMoveRequest(); Request.SetGoalActor(CurrentWaypoint); Request.SetUsePathfinding(true); @@ -352,7 +351,7 @@ void UVHMovement::ChildMoveToWaypoint() if (IntermediatePointIterator < intermediatePoints.Num()) { auto path = navSys->FindPathToLocationSynchronously(GetWorld(), AVirtualHumanPawn->GetActorLocation(), - intermediatePoints[IntermediatePointIterator]); + intermediatePoints[IntermediatePointIterator]); FAIMoveRequest request = FAIMoveRequest(); request.SetUsePathfinding(true); @@ -367,7 +366,7 @@ void UVHMovement::ChildMoveToWaypoint() // calculate the speed towards the lastPointOfCurrentPath (therefore + 1) speed = CalculateChildSpeed(CurrentWaypoint, intermediatePoints[IntermediatePointIterator + 1]); speed = FMath::Clamp(speed, 0.0f, - FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.5f, MAX_WALKING_SPEED)); + FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.5f, MAX_WALKING_SPEED)); Cast<UCharacterMovementComponent>(AVirtualHumanPawn->GetMovementComponent())->MaxWalkSpeed = speed; } else // we are on the inside and need to slow down @@ -375,7 +374,7 @@ void UVHMovement::ChildMoveToWaypoint() speed = CalculateChildSpeed(CurrentWaypoint, intermediatePoints[IntermediatePointIterator]); // calculate the speed towards the inner point speed = FMath::Clamp(speed, 0.0f, - FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.5f, MAX_WALKING_SPEED)); + FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.5f, MAX_WALKING_SPEED)); Cast<UCharacterMovementComponent>(AVirtualHumanPawn->GetMovementComponent())->MaxWalkSpeed = speed; } } @@ -385,7 +384,7 @@ void UVHMovement::ChildMoveToWaypoint() { speed = CalculateChildSpeed(CurrentWaypoint, intermediatePoints); speed = FMath::Clamp(speed, 0.0f, - FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.3f, MAX_WALKING_SPEED)); + FMath::Min(CurrentWaypoint->GetWalkingSpeed() * 1.3f, MAX_WALKING_SPEED)); Cast<UCharacterMovementComponent>(AVirtualHumanPawn->GetMovementComponent())->MaxWalkSpeed = speed; } CurrentRequestID = VirtualHumanAIController->RequestMove(request, path->GetPath()); @@ -439,76 +438,73 @@ void UVHMovement::WaypointMovement() // sort Waypoint array accordingly switch (WaypointOrder) { - case Closest: + case Closest: - // first we find the closest waypoint to the VAs position, then we sort the array according to the distance between the waypoints + // first we find the closest waypoint to the VAs position, then we sort the array according to the distance between the waypoints - // first we sort by distance to VA - // we compare the distance of the path on the nav mesh, not the euclidean distance - Waypoints.Sort([AVHPawn, World](AWaypoint& a, AWaypoint& b) - { - // only works if NavigationSystem is included in build.cs - UNavigationPath* NpathToA = UNavigationSystemV1::FindPathToLocationSynchronously( - World, AVHPawn->GetActorLocation(), a.GetActorLocation()); + // first we sort by distance to VA + // we compare the distance of the path on the nav mesh, not the euclidean distance + Waypoints.Sort([AVHPawn, World](AWaypoint& a, AWaypoint& b) { + // only works if NavigationSystem is included in build.cs + UNavigationPath* NpathToA = UNavigationSystemV1::FindPathToLocationSynchronously( + World, AVHPawn->GetActorLocation(), a.GetActorLocation()); - UNavigationPath* NpathToB = UNavigationSystemV1::FindPathToLocationSynchronously( - World, AVHPawn->GetActorLocation(), b.GetActorLocation()); + UNavigationPath* NpathToB = UNavigationSystemV1::FindPathToLocationSynchronously( + World, AVHPawn->GetActorLocation(), b.GetActorLocation()); - float distanceToA = NpathToA->GetPathLength(); //GetPathLength() is potentially slow says unreal - float distanceToB = NpathToB->GetPathLength(); - - return distanceToA < distanceToB; - }); + float distanceToA = NpathToA->GetPathLength(); //GetPathLength() is potentially slow says unreal + float distanceToB = NpathToB->GetPathLength(); + return distanceToA < distanceToB; + }); // then sort by distance from one WP to the next one - for (int i = 1; i < Waypoints.Num(); ++i) - { - for (int j = 2; j < Waypoints.Num(); ++j) + for (int i = 1; i < Waypoints.Num(); ++i) { - if (j < i) - { - continue; - } - UNavigationPath* NpathToi = UNavigationSystemV1::FindPathToLocationSynchronously( - GetWorld(), Waypoints[i - 1]->GetActorLocation(), Waypoints[i]->GetActorLocation()); - - UNavigationPath* NpathToJ = UNavigationSystemV1::FindPathToLocationSynchronously( - GetWorld(), Waypoints[i - 1]->GetActorLocation(), Waypoints[j]->GetActorLocation()); - - float distanceToI = NpathToi->GetPathLength(); //GetPathLength() is potentially slow says unreal - float distanceToJ = NpathToJ->GetPathLength(); - - if (distanceToI > distanceToJ) + for (int j = 2; j < Waypoints.Num(); ++j) { - Waypoints.Swap(i, j); + if (j < i) + { + continue; + } + UNavigationPath* NpathToi = UNavigationSystemV1::FindPathToLocationSynchronously( + GetWorld(), Waypoints[i - 1]->GetActorLocation(), Waypoints[i]->GetActorLocation()); + + UNavigationPath* NpathToJ = UNavigationSystemV1::FindPathToLocationSynchronously( + GetWorld(), Waypoints[i - 1]->GetActorLocation(), Waypoints[j]->GetActorLocation()); + + float distanceToI = NpathToi->GetPathLength(); //GetPathLength() is potentially slow says unreal + float distanceToJ = NpathToJ->GetPathLength(); + + if (distanceToI > distanceToJ) + { + Waypoints.Swap(i, j); + } + /* + * if GetPathLength() above is too slow we could use the euclidian distance + if(Waypoints[i-1]->GetDistanceTo(Waypoints[i]) > Waypoints[i-1]->GetDistanceTo(Waypoints[j])) + { + Waypoints.Swap(i, j); + } + */ } - /* - * if GetPathLength() above is too slow we could use the euclidian distance - if(Waypoints[i-1]->GetDistanceTo(Waypoints[i]) > Waypoints[i-1]->GetDistanceTo(Waypoints[j])) - { - Waypoints.Swap(i, j); - } - */ } - } - break; + break; - case Manual: + case Manual: - Waypoints.Sort([](AWaypoint& a, AWaypoint& b) - { - return a.GetWaypointOrder() < b.GetWaypointOrder(); - }); - break; + Waypoints.Sort([](AWaypoint& a, AWaypoint& b) { + return a.GetWaypointOrder() < b.GetWaypointOrder(); + }); + break; - case Random: - Waypoints = ShuffleArray(Waypoints); - break; + case Random: + Waypoints = ShuffleArray(Waypoints); + break; - default: - VH_ERROR("Waypoint Handling is not specified\n"); - break; // cannot be reached + default: + VH_ERROR("Waypoint Handling is not specified\n"); + break; // cannot be reached } // if we are the parent, we set the Waypoints for our childs @@ -554,7 +550,6 @@ void UVHMovement::WaypointMovement() } } - if (Waypoints.Num() < 1) { // in case we are still empty, there is no a failure @@ -562,7 +557,6 @@ void UVHMovement::WaypointMovement() return; } - if (bChild) { CreateChildPoints(); @@ -606,77 +600,77 @@ void UVHMovement::CreateChildPoints() FVector startingPosition; switch (GroupFormation) { - case Abreast: - if (Waypoints.Num() > 1) - { - // around first waypoint from starting position - startingPosition = CreateIntermediatePoints(NULL, Waypoints[0], Waypoints[1])[0]; + case Abreast: + if (Waypoints.Num() > 1) + { + // around first waypoint from starting position + startingPosition = CreateIntermediatePoints(NULL, Waypoints[0], Waypoints[1])[0]; + + // around 2nd to last -1 + for (int i = 1; i < Waypoints.Num() - 1; i++) + { + ChildPoints.Add(Waypoints[i], + (CreateIntermediatePoints(Waypoints[i - 1], Waypoints[i], Waypoints[i + 1]))); + } + + // around last waypoint + ChildPoints.Add(Waypoints.Last(), + CreateIntermediatePoints(Waypoints.Last(1), Waypoints.Last(), Waypoints[0])); - // around 2nd to last -1 - for (int i = 1; i < Waypoints.Num() - 1; i++) + // around first waypoint from last waypoint + if (IsLoop()) + { + ChildPoints.Add(Waypoints[0], CreateIntermediatePoints(Waypoints.Last(), Waypoints[0], Waypoints[1])); + } + MoveToWaypoint(startingPosition, CalculateChildSpeed(Waypoints[0], startingPosition)); + } + else { - ChildPoints.Add(Waypoints[i], - (CreateIntermediatePoints(Waypoints[i - 1], Waypoints[i], Waypoints[i + 1]))); + // only one waypoint + startingPosition = CreateIntermediatePoints(NULL, Waypoints[0], Waypoints[0])[0]; + MoveToWaypoint(startingPosition, CalculateChildSpeed(Waypoints[0], startingPosition)); } + break; - // around last waypoint - ChildPoints.Add(Waypoints.Last(), - CreateIntermediatePoints(Waypoints.Last(1), Waypoints.Last(), Waypoints[0])); - - // around first waypoint from last waypoint - if (IsLoop()) + case InLine: + bLineMovement = true; + AWaypoint* first; + AWaypoint* next; + FVector direction; + // we just need an aditional starting point that the child moves to in the time the parent walks to the first waypoint + if (Waypoints.Num() > 1) { - ChildPoints.Add(Waypoints[0], CreateIntermediatePoints(Waypoints.Last(), Waypoints[0], Waypoints[1])); + first = Waypoints[0]; + next = Waypoints[1]; + direction = first->GetActorLocation() - next->GetActorLocation(); + } + else + { + first = Waypoints[0]; + direction = ParentVH->GetActorLocation() - first->GetActorLocation(); } - MoveToWaypoint(startingPosition, CalculateChildSpeed(Waypoints[0], startingPosition)); - } - else - { - // only one waypoint - startingPosition = CreateIntermediatePoints(NULL, Waypoints[0], Waypoints[0])[0]; - MoveToWaypoint(startingPosition, CalculateChildSpeed(Waypoints[0], startingPosition)); - } - break; - - case InLine: - bLineMovement = true; - AWaypoint* first; - AWaypoint* next; - FVector direction; - // we just need an aditional starting point that the child moves to in the time the parent walks to the first waypoint - if (Waypoints.Num() > 1) - { - first = Waypoints[0]; - next = Waypoints[1]; - direction = first->GetActorLocation() - next->GetActorLocation(); - } - else - { - first = Waypoints[0]; - direction = ParentVH->GetActorLocation() - first->GetActorLocation(); - } - direction.Normalize(); - FVector offsetToChildStartingPoint = OffsetFromWaypoint * direction; - startingPosition = first->GetActorLocation() + offsetToChildStartingPoint; + direction.Normalize(); + FVector offsetToChildStartingPoint = OffsetFromWaypoint * direction; + startingPosition = first->GetActorLocation() + offsetToChildStartingPoint; - float childSpeed = CalculateChildSpeed(first, startingPosition); + float childSpeed = CalculateChildSpeed(first, startingPosition); - // we skip walking to the first waypoint if: - // the child walks in front of the parent or we only have one waypoint, then the child just walks to the starting position - if (OffsetFromWaypoint < 0 || Waypoints.Num() == 1) - { - CurrentWaypointIterator++; - } + // we skip walking to the first waypoint if: + // the child walks in front of the parent or we only have one waypoint, then the child just walks to the starting position + if (OffsetFromWaypoint < 0 || Waypoints.Num() == 1) + { + CurrentWaypointIterator++; + } - MoveToWaypoint(startingPosition, childSpeed); - //after this is done VirtualHumanAIController will automatically call MoveToWaypoint() + MoveToWaypoint(startingPosition, childSpeed); + //after this is done VirtualHumanAIController will automatically call MoveToWaypoint() - if (bDrawDebugSpheres) - { - DrawDebugSphere(GetWorld(), startingPosition, 50.0f, 30.0f, FColor::Green, true); - } - break; + if (bDrawDebugSpheres) + { + DrawDebugSphere(GetWorld(), startingPosition, 50.0f, 30.0f, FColor::Green, true); + } + break; } } @@ -725,7 +719,7 @@ TArray<FVector> UVHMovement::CreateIntermediatePoints(AWaypoint* lastWP, AWaypoi // create speedUpPoint if we are on the outside path: // we make a right turn and offset is to the left or we make a left turn and offset is to the right if ((angleInMoveDir > 0 && lastWP != NULL && OffsetFromWaypoint > 0) || (angleInMoveDir < 0 && lastWP != NULL && - OffsetFromWaypoint < 0)) + OffsetFromWaypoint < 0)) { //calculate a point towards the end of the path to the next waypoint at which the child begins to walk faster (if he has the outside path) FVector speedUpPoint = LastPointOfCurrentPath - 0.40 * (current - last); @@ -750,7 +744,7 @@ TArray<FVector> UVHMovement::CreateIntermediatePoints(AWaypoint* lastWP, AWaypoi if (angleInMoveDir > 140) { OffsetFromWaypoint = -1 * OffsetFromWaypoint; // side change - angleInMoveDir -= 180; // for the remaining angle we still calculate intermediate points + angleInMoveDir -= 180; // for the remaining angle we still calculate intermediate points } if (angleInMoveDir < -140) { @@ -761,7 +755,7 @@ TArray<FVector> UVHMovement::CreateIntermediatePoints(AWaypoint* lastWP, AWaypoi // create intermediate points if we are on the outside path: // we make a right turn and offset is to the left or we make a left turn and offset is to the right if ((angleInMoveDir > 0 && lastWP != NULL && OffsetFromWaypoint > 0) || (angleInMoveDir < 0 && lastWP != NULL && - OffsetFromWaypoint < 0)) + OffsetFromWaypoint < 0)) { // intermediate point (especially usefull if angles between waypoints is very big) // could be neglected for perfromace reasons @@ -773,7 +767,6 @@ TArray<FVector> UVHMovement::CreateIntermediatePoints(AWaypoint* lastWP, AWaypoi FVector firstPointOfNextPathOffset = childLocationOffset.RotateAngleAxis(angleInMoveDir, FVector(0, 0, 1)); FVector firstPointOfNextPath = current + firstPointOfNextPathOffset; - newPoints.Add(firstPointOfNextPath); if (bDrawDebugSpheres) @@ -865,4 +858,4 @@ FHitResult UVHMovement::IKFootTrace(const FName& Socket) const GetWorld()-> LineTraceSingleByChannel(Hit, LineTraceStart, LineTraceEnd, ECC_Visibility, TraceParams); return Hit; -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/VHPointing.cpp b/Source/CharacterPlugin/Private/VHPointing.cpp index b985555d2c5b48d69b3e949662492c6aaac81584..e59cd52830fe1ae160b672e7faa85a12ea0873ca 100644 --- a/Source/CharacterPlugin/Private/VHPointing.cpp +++ b/Source/CharacterPlugin/Private/VHPointing.cpp @@ -18,15 +18,19 @@ void UVHPointing::BeginPlay() void UVHPointing::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - if (VHAnimInstance == nullptr) { + if (VHAnimInstance == nullptr) + { AVirtualHuman* owner = Cast<AVirtualHuman>(GetOwner()); - if (owner != nullptr) { + if (owner != nullptr) + { VHAnimInstance = owner->GetBodyAnimInstance(); } - else { + else + { VHAnimInstance = Cast<UVHAnimInstance>(Cast<USkeletalMeshComponent>(GetOwner()->GetComponentByClass(USkeletalMeshComponent::StaticClass()))->GetAnimInstance()); } - if (!VHAnimInstance) { + if (!VHAnimInstance) + { VH_ERROR("[UVHPointing::TickComponent] No VHAnimInstance component attached"); } } @@ -38,12 +42,14 @@ void UVHPointing::TickComponent(float DeltaTime, ELevelTick TickType, FActorComp FVector DirVHTarget = PointingTarget - GetOwner()->GetActorLocation(); float AngleLeftRight = FVector::DotProduct(FVector::CrossProduct(GetOwner()->GetActorUpVector().GetSafeNormal(), DirVHTarget.GetSafeNormal()), GetOwner()->GetActorForwardVector().GetSafeNormal()); float AngleFrontTarget = FMath::Acos(FVector::DotProduct(DirVHTarget.GetSafeNormal(), GetOwner()->GetActorForwardVector().GetSafeNormal())); - if (AngleFrontTarget > (180-BlindAngle)*PI/180.0) { + if (AngleFrontTarget > (180 - BlindAngle) * PI / 180.0) + { VHAnimInstance->PointingUseHand = EPointingHand::HandNone; } - else + else { - if (AngleLeftRight > 0) { + if (AngleLeftRight > 0) + { VHAnimInstance->PointingUseHand = EPointingHand::HandLeft; } else @@ -56,8 +62,7 @@ void UVHPointing::TickComponent(float DeltaTime, ELevelTick TickType, FActorComp { VHAnimInstance->PointingUseHand = EPointingHand::HandNone; } - + } - -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/VirtualHuman.cpp b/Source/CharacterPlugin/Private/VirtualHuman.cpp index 126bbc06285a035c6229b6c28436c8b1b4319167..f82ff653b7b93d13930d189d05e3b0007cefbfa8 100644 --- a/Source/CharacterPlugin/Private/VirtualHuman.cpp +++ b/Source/CharacterPlugin/Private/VirtualHuman.cpp @@ -168,7 +168,8 @@ bool AVirtualHuman::SupportsMorphs() bool AVirtualHuman::ForcePlayNewIdleAnimation() { - if (CustomIdleAnimations.IsEmpty()) return false; + if (CustomIdleAnimations.IsEmpty()) + return false; NextIdleTimerHandle.Invalidate(); PlayRandomIdleAnimation(); @@ -242,7 +243,7 @@ void AVirtualHuman::SetUpBodyType() UObject* face_skeleton_obj = AssetLoader2.LoadSynchronous(AssetRef2); if (root_obj != nullptr && body != nullptr && body_skeleton_obj != nullptr && face != nullptr && - face_skeleton_obj != nullptr) + face_skeleton_obj != nullptr) { USceneComponent* root = Cast<USceneComponent>(root_obj); USkeleton* body_skel = Cast<USkeleton>(body_skeleton_obj); @@ -331,9 +332,7 @@ void AVirtualHuman::PlayRandomIdleAnimation() IdleAnim, "CustomIdleSlot", BlendTime, BlendTime); // start timer for next random pick (make it a bit shorter to allow for blending, but only by a defined minimal amount for the animations) GetWorld()->GetTimerManager().SetTimer(NextIdleTimerHandle, this, &AVirtualHuman::PlayRandomIdleAnimation, - DynamicMontage->GetPlayLength() - fmin( - 2.0 * BlendTime, (DynamicMontage->GetPlayLength()) * MinBlendTime), - false); + DynamicMontage->GetPlayLength() - fmin(2.0 * BlendTime, (DynamicMontage->GetPlayLength()) * MinBlendTime), false); } else { @@ -358,4 +357,4 @@ void AVirtualHuman::OnConstruction(const FTransform& Transform) { Super::OnConstruction(Transform); SetUpBodyType(); -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/VirtualHumanAIController.cpp b/Source/CharacterPlugin/Private/VirtualHumanAIController.cpp index 74b01b526dd915a3f97c1fe21bbe6fec94cac691..9745b7460b728bfb45c0f59465d6b6aa66914278 100644 --- a/Source/CharacterPlugin/Private/VirtualHumanAIController.cpp +++ b/Source/CharacterPlugin/Private/VirtualHumanAIController.cpp @@ -26,7 +26,7 @@ void AVirtualHumanAIController::PostProcessMovement(UPathFollowingComponent* Com TArray<AVHsManager*> MyManagers = GetAssociatedVHsManagers(); if (MyManagers.Num() > 0) { - for (AVHsManager *manager : MyManagers) + for (AVHsManager* manager : MyManagers) { if (manager != nullptr && manager->DebugDraw) { @@ -60,23 +60,23 @@ void AVirtualHumanAIController::PostProcessMovement(UPathFollowingComponent* Com } VelocityPostProcessor->PostProcessVelocity(LastDeltaTime, Velocity); - } void AVirtualHumanAIController::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) { UVHMovement* Movement = Cast<UVHMovement>(GetPawn()->FindComponentByClass<UVHMovement>()); - if(Movement) + if (Movement) { - if(Movement->CurrentRequestID != RequestID) + if (Movement->CurrentRequestID != RequestID) { return; } - if (Movement->ShouldChildMove() && Movement->IsChild() && !Movement->IsLineMovement()) { + if (Movement->ShouldChildMove() && Movement->IsChild() && !Movement->IsLineMovement()) + { Movement->ChildMoveToWaypoint(); } - else if(!Movement->IsChild() || Movement->IsLineMovement()) + else if (!Movement->IsChild() || Movement->IsLineMovement()) { Movement->MoveToWaypoint(); } @@ -106,13 +106,13 @@ TArray<AVHsManager*> AVirtualHumanAIController::GetAssociatedVHsManagers() // Get all managers in the scene TArray<AActor*> AllManagers; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AVHsManager::StaticClass(), AllManagers); - + // Try to find out if we belong to a manger if (AllManagers.Num() > 0) { AVirtualHuman* Agent = Cast<AVirtualHuman>(GetPawn()); //VH_DEBUG("Name of current agent is %s", *OwnerAgent->GetName()); - for (AActor *a : AllManagers) + for (AActor* a : AllManagers) { AVHsManager* VHsManager = Cast<AVHsManager>(a); if (VHsManager->HasAgent(Agent)) @@ -122,4 +122,4 @@ TArray<AVHsManager*> AVirtualHumanAIController::GetAssociatedVHsManagers() } } return MyManagers; -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Private/Waypoint.cpp b/Source/CharacterPlugin/Private/Waypoint.cpp index b2820984bcf98e7338ab4bb5cce8020abaea0d80..1c1632ac56559c1fc3e2db3f5b06171710c7899c 100644 --- a/Source/CharacterPlugin/Private/Waypoint.cpp +++ b/Source/CharacterPlugin/Private/Waypoint.cpp @@ -30,4 +30,4 @@ int AWaypoint::GetWaypointGroup() const int AWaypoint::GetLastWaypointCommand() const { return OnReachLastWaypoint; -} +} \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/AnimNodes/AnimNode_VHGazing.h b/Source/CharacterPlugin/Public/AnimNodes/AnimNode_VHGazing.h index e0538785d08145aa38448c21155e3f2731c437d5..8b88e90a8e27acae063ca1ffc683cfaa5d35ffbe 100644 --- a/Source/CharacterPlugin/Public/AnimNodes/AnimNode_VHGazing.h +++ b/Source/CharacterPlugin/Public/AnimNodes/AnimNode_VHGazing.h @@ -108,7 +108,6 @@ struct CHARACTERPLUGIN_API FAnimNode_VHGazing : public FAnimNode_Base GENERATED_USTRUCT_BODY() protected: - // Input link UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Links) FPoseLink InputPose; @@ -135,9 +134,7 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = VHGazing, meta = (PinShownByDefault)) FRotator AdditionalHeadRotation = FRotator::ZeroRotator; - public: - // FAnimNode_Base interface virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) override; @@ -151,7 +148,6 @@ public: static FRotator GetYawPitchRotationBetween(FVector From, FVector To); private: - void UpdateRotations(FPoseContext& PoseContext, FComponentSpacePoseContext& CSPoseContext); void ApplyRotation(FGazingBoneData& GazingBoneData, FRotator Rotation, FPoseContext& PoseContext, FComponentSpacePoseContext& CSPoseContext); @@ -175,4 +171,4 @@ private: const FReferenceSkeleton* RefSkel = nullptr; float DeltaTime; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/AnimNodes/ModifyCurvesNode.h b/Source/CharacterPlugin/Public/AnimNodes/ModifyCurvesNode.h index a52b0ceebb07331bc35f974ea8ad2e3106205af4..de0056706ffc6e0f8701f395b31ba9c75d6a516f 100644 --- a/Source/CharacterPlugin/Public/AnimNodes/ModifyCurvesNode.h +++ b/Source/CharacterPlugin/Public/AnimNodes/ModifyCurvesNode.h @@ -54,4 +54,4 @@ struct CHARACTERPLUGIN_API FModifyCurvesNode : public FAnimNode_Base virtual void Evaluate_AnyThread(FPoseContext& Output) override; virtual void Update_AnyThread(const FAnimationUpdateContext& Context) override; // End of FAnimNode_Base interface -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/CharacterPlugin.h b/Source/CharacterPlugin/Public/CharacterPlugin.h index c2494c14454e66a9adb58333975edf66e3cec02a..02346b75e58a21a8457e0b7a9e48a9f103051182 100644 --- a/Source/CharacterPlugin/Public/CharacterPlugin.h +++ b/Source/CharacterPlugin/Public/CharacterPlugin.h @@ -6,6 +6,6 @@ class FCharacterPluginModule : public IModuleInterface { public: - virtual void StartupModule () override; - virtual void ShutdownModule() override; -}; + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/Crowds/Predictive.h b/Source/CharacterPlugin/Public/Crowds/Predictive.h index 174d7c91457627a71280893aa7a88e99afdb5766..fc7204c3c10e8da805d4c80aee1d1bf373d62ea3 100644 --- a/Source/CharacterPlugin/Public/Crowds/Predictive.h +++ b/Source/CharacterPlugin/Public/Crowds/Predictive.h @@ -20,49 +20,49 @@ public: // These following values come directly from the Karamouzas paper (see cpp) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float ORIENT_WEIGHT = 0.8f; - + float ORIENT_WEIGHT = 0.8f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float COS_FOV_ANGLE = FMath::Cos(FMath::DegreesToRadians(100.f)); // 100 degrees (200 total) - + float COS_FOV_ANGLE = FMath::Cos(FMath::DegreesToRadians(100.f)); // 100 degrees (200 total) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float REACTION_TIME = 0.4f; - + float REACTION_TIME = 0.4f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float WALL_STEEPNESS = 2.f; - + float WALL_STEEPNESS = 2.f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float WALL_DISTANCE = 0.4f; - + float WALL_DISTANCE = 0.4f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - int COLLIDING_COUNT = 5; // K most dangerous neighbors considered - + int COLLIDING_COUNT = 5; // K most dangerous neighbors considered + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float D_MIN = 1.f; - + float D_MIN = 1.f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float D_MID = 8.f; - + float D_MID = 8.f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float D_MAX = 10.f; - + float D_MAX = 10.f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float AGENT_FORCE = 3.f; // how many Newtons? - + float AGENT_FORCE = 3.f; // how many Newtons? + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float RADIUS = 0.45f; // m - + float RADIUS = 0.45f; // m + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float MAX_ACCELERATION = 200.f; - + float MAX_ACCELERATION = 200.f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float PERSONAL_SPACE = 1.f; + float PERSONAL_SPACE = 1.f; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float ANTICIPATION_TIME = 3.f; + float ANTICIPATION_TIME = 3.f; private: float RayCircleTTC(const FVector2D& Dir, const FVector2D& Center, float Radius); FRandomStream CrowdsPredictiveRandomStream; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/Crowds/Spawner/AgentSpawner.h b/Source/CharacterPlugin/Public/Crowds/Spawner/AgentSpawner.h index e491f76d84e1687ff09645703c68637fac5d6731..202769198ef499bca560eb85fdf8dad2e0404a9a 100644 --- a/Source/CharacterPlugin/Public/Crowds/Spawner/AgentSpawner.h +++ b/Source/CharacterPlugin/Public/Crowds/Spawner/AgentSpawner.h @@ -29,18 +29,18 @@ public: /**Time deltas for respawning in seconds; 0 means just spawning once. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpawnGroup") - float RespawnRate = 0.0f; + float RespawnRate = 0.0f; /**How many agents should be spawned per trigger? */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpawnGroup") - int GroupSize = 10; + int GroupSize = 10; /** Which waypoing group is associated with this spawner? */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpawnGroup") - int WaypointGroup; + int WaypointGroup; /** With which manager is the spawner associated? */ UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(UseComponentPicker), Category = "SpawnGroup") - AVHsManager* VHsManager; + AVHsManager* VHsManager; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/Crowds/Spawner/CircleSpawner.h b/Source/CharacterPlugin/Public/Crowds/Spawner/CircleSpawner.h index 7c580caa8760a44405ffb1b852a3fa086dcd2d5c..cd62b9ffee8f7d7f4a91f3c9675c4bb2a0d9405b 100644 --- a/Source/CharacterPlugin/Public/Crowds/Spawner/CircleSpawner.h +++ b/Source/CharacterPlugin/Public/Crowds/Spawner/CircleSpawner.h @@ -16,10 +16,10 @@ class CHARACTERPLUGIN_API ACircleSpawner : public AAgentSpawner public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SpawnCircle) - float SpawnRadius = 250.0f; + float SpawnRadius = 250.0f; void BeginPlay() override; void Spawn() override; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/Crowds/VHsManager.h b/Source/CharacterPlugin/Public/Crowds/VHsManager.h index 9d02f62ed1405793f75f4b816c6dc7eccdbf1e98..b30d189129851f930a46ce10829423f402cea68c 100644 --- a/Source/CharacterPlugin/Public/Crowds/VHsManager.h +++ b/Source/CharacterPlugin/Public/Crowds/VHsManager.h @@ -29,16 +29,15 @@ protected: virtual void BeginPlay() override; public: - AVirtualHuman* SpawnVH(FVector Position, bool IgnoreCollisions = false); void ClearAllVHs(); - void Add(AVirtualHuman * agent); + void Add(AVirtualHuman* agent); - void Remove(AVirtualHuman * agent); + void Remove(AVirtualHuman* agent); - bool HasAgent(AVirtualHuman * Agent); + bool HasAgent(AVirtualHuman* Agent); UFUNCTION(BlueprintCallable) void SetCrowdAlgorithm(TSubclassOf<UVelocityPostProcessorComponent> NewCrowdAlgorithm); @@ -55,11 +54,10 @@ public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "VHManager") bool DebugDraw = false; - -private: +private: void SetCrowdAlgorithmFor(AVirtualHuman* VH); TArray<AVirtualHuman*> AllVHs; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/Crowds/VelocityPostProcessorComponent.h b/Source/CharacterPlugin/Public/Crowds/VelocityPostProcessorComponent.h index bf982747e9a6ce8d37256d05d977587d254e399b..b06113487892cc504afcbe67b839238a592e5dcc 100644 --- a/Source/CharacterPlugin/Public/Crowds/VelocityPostProcessorComponent.h +++ b/Source/CharacterPlugin/Public/Crowds/VelocityPostProcessorComponent.h @@ -25,8 +25,8 @@ public: // 140cm/s is the average of comfortable gait speeds for women and men in their 20s to 50s UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float WALK_SPEED = 140; // cm/s + float WALK_SPEED = 140; // cm/s UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VelocityPostProcessor") - float NEIGHBOUR_DIST_LIMIT_SQUARE = 1000 * 1000; // cm -}; + float NEIGHBOUR_DIST_LIMIT_SQUARE = 1000 * 1000; // cm +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroup.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroup.h index 858da709976469b9d36317d37bdfbad7469aa031..c744f17032319795c0d0611cbe5fef6721b6c7c0 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroup.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroup.h @@ -26,19 +26,19 @@ struct FSocialConstraints GENERATED_BODY() UPROPERTY() - float MinimalDistance = 110.0f; + float MinimalDistance = 110.0f; UPROPERTY() - float IntimateDistance = 45.0f; + float IntimateDistance = 45.0f; UPROPERTY() - float PersonalDistance = 120.0f; + float PersonalDistance = 120.0f; UPROPERTY() - float SocialDistance = 360.0f; + float SocialDistance = 360.0f; UPROPERTY() - float PublicDistance = 760.0f; + float PublicDistance = 760.0f; }; @@ -48,102 +48,102 @@ struct FAgentDialogueUtterance GENERATED_BODY() UPROPERTY() - FDialogueUtterance Utterance; + FDialogueUtterance Utterance; UPROPERTY() - AVirtualHuman* VH; + AVirtualHuman* VH; }; UCLASS() class CHARACTERPLUGIN_API ASocialGroup : public AActor { GENERATED_BODY() - -public: + +public: // Sets default values for this actor's properties ASocialGroup(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; - + public: // Called every frame virtual void Tick(float DeltaTime) override; - + UPROPERTY(EditAnywhere, Category = "SocialGroup", meta= (EditCondition = "!bSpawnAsGroup")) - TArray<AVirtualHuman*> AgentsInGroup; + TArray<AVirtualHuman*> AgentsInGroup; // If true, GroupSize determines how many agents will spawn at start UPROPERTY(EditAnywhere, Category = "SocialGroup") - bool bSpawnAsGroup; + bool bSpawnAsGroup; // Only editable if spawn VH on start is true UPROPERTY(EditAnywhere, Category = "SocialGroup", meta = (EditCondition = "bSpawnAsGroup")) - int GroupSize; + int GroupSize; // Types of Virtual Human that should be spawned UPROPERTY(EditAnywhere, Category = "SocialGroup", meta = (EditCondition = "bSpawnAsGroup")) - TArray<TSubclassOf<AVirtualHuman>> VHTypes; + TArray<TSubclassOf<AVirtualHuman>> VHTypes; + - // Minimal Distance VAs keep to each other and the user UPROPERTY(EditAnywhere, Category = "SocialGroup") - float ConversationDistance = 140.0f; + float ConversationDistance = 140.0f; // Distance at which the user is still recognizable UPROPERTY(EditAnywhere, Category = "SocialGroup") - float GazeDistance = 220.0f; + float GazeDistance = 220.0f; // Variance in which the user can move before a leave is detected UPROPERTY(EditAnywhere, Category = "SocialGroup") - float StillStandingVariance = 100.0f; + float StillStandingVariance = 100.0f; // Distance at which a join can be detected UPROPERTY(EditAnywhere, Category = "SocialGroup") - float JoinDistance = 100.0f; + float JoinDistance = 100.0f; // If the users orientation to the group is below this angle, he is classified as oriented towards the group UPROPERTY(EditAnywhere, Category = "SocialGroup") - float ToGroupThreshold = 30.0f; + float ToGroupThreshold = 30.0f; // dialogue setup: - - + + UPROPERTY(EditAnywhere, Category = "SocialGroup|Dialogue") - bool bStartDialogue; + bool bStartDialogue; // contains data for speaking like sound file, face animation data and start of face animation UPROPERTY(EditAnywhere, Category = "SocialGroup|Dialogue") - TArray<FDialogueUtterance> Dialogue; + TArray<FDialogueUtterance> Dialogue; // on how many agents will the dialogue be distributed UPROPERTY(EditAnywhere, Category = "SocialGroup|Dialogue") - int NumberOfAgentsInConversation; + int NumberOfAgentsInConversation; UPROPERTY(EditAnywhere, Category = "SocialGroup|Dialogue") - bool bLoopDialogue; - + bool bLoopDialogue; + UFUNCTION(BlueprintCallable) - void LeaveGroup(AVirtualHuman* VH); + void LeaveGroup(AVirtualHuman* VH); UFUNCTION(BlueprintCallable) - void JoinGroup(AVirtualHuman* VH); + void JoinGroup(AVirtualHuman* VH); UFUNCTION() AActor* GetSpeaker(); - + UVHSocialGroups* GetSocialGroupsComponent(AVirtualHuman* VH) const; UVHGazing* GetGazingComponent(AVirtualHuman* VH) const; UVHSpeech* GetSpeechComponent(AVirtualHuman* VH) const; TArray<FVector> GetCirclePositions(int NumberOfAgents); - + FVector TrackedPawnLocation; UPROPERTY() - APawn* AgentPawn; + APawn* AgentPawn; UPROPERTY() - ARWTHVRPawn* VRPawn; + ARWTHVRPawn* VRPawn; void ChangeState(TScriptInterface<ISocialGroupState> NextState); @@ -153,18 +153,18 @@ public: // Start dialogue after the initial delay. // Requires VHSpeech, VHFaceAnimation(like VHLiveLinkFaceAnimation) and VAAudiofileSourceComponent. UFUNCTION(BlueprintCallable) - bool StartDialogue(float InitialDelay); + bool StartDialogue(float InitialDelay); UFUNCTION(BlueprintCallable) - void StopDialogue(); + void StopDialogue(); void NextDialogue(); void PauseDialogue(float Duration); //preloads the dialogue. However, since audiofiles are loaded for all agents this can take some time UFUNCTION(BlueprintCallable) - void PreloadDialogue(); - + void PreloadDialogue(); + float GroupRadius; bool bPlayerIsInGroup; @@ -176,25 +176,24 @@ public: void RestartDialogue(float InitialDelay); void StartRandomGazingTimer(float FirstDelay); void StartRandomGazing(); - + // Animation Montages UPROPERTY() - TArray<UAnimMontage*> WavingMontages; - + TArray<UAnimMontage*> WavingMontages; + // States UPROPERTY() - USG_Idle* Idle; + USG_Idle* Idle; UPROPERTY() - USG_Gazing* Gazing; + USG_Gazing* Gazing; UPROPERTY() - USG_Leaving* Leaving; + USG_Leaving* Leaving; UPROPERTY() - USG_InGroup* InGroup; + USG_InGroup* InGroup; UPROPERTY() - TArray<TScriptInterface<ISocialGroupState>> GroupStates; - -private: + TArray<TScriptInterface<ISocialGroupState>> GroupStates; +private: TArray<AVirtualHuman*> SpawnInGroupFormation(); FTimerHandle SpeakerTimerHandle; @@ -206,23 +205,23 @@ private: FTimerHandle RandomGazingTimer; UFUNCTION() - void OnSphereBeginOverlap(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); + void OnSphereBeginOverlap(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); UFUNCTION() - void OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); + void OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); bool SetupDialogue(); UPROPERTY() - TArray<FAgentDialogueUtterance> AgentsInConversation; - + TArray<FAgentDialogueUtterance> AgentsInConversation; + static TArray<AVirtualHuman*> ShuffleArray(TArray<AVirtualHuman*> Agents); bool bAgentIsJoining; UPROPERTY() - AVirtualHuman* JoiningAgent; + AVirtualHuman* JoiningAgent; UPROPERTY() - USphereComponent* CollisionSphere; + USphereComponent* CollisionSphere; UPROPERTY() - TArray<AVirtualHuman*> CloseAgents; + TArray<AVirtualHuman*> CloseAgents; TArray<UAnimMontage*> LoadAnimationMontages() const; int TrackedAgentIt; @@ -230,5 +229,4 @@ private: void DestroyAgent(); -}; - +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupState.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupState.h index 144b8626d0df6cd8d9712e188046b1e5ffd9f2ad..552b39e112b314e7e0b17a9c58f28f93c958f95e 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupState.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupState.h @@ -29,4 +29,4 @@ public: virtual void ToGazing(ASocialGroup* SG); virtual void ToInGroup(ASocialGroup* SG); virtual void ToLeaving(ASocialGroup* SG); -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Gazing.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Gazing.h index 9762692cd30348432941efa40f4160a63f25eb6b..6706945e536d49eba3d31c8eb0344a5bd629da91 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Gazing.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Gazing.h @@ -24,4 +24,4 @@ public: private: FRandomStream SGGazingRandomStream; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Idle.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Idle.h index 26d38a57975bf273b48a08526427c0540e582e87..e40650bc39598a08d034b80dff83f87b65a168e9 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Idle.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Idle.h @@ -18,5 +18,5 @@ class CHARACTERPLUGIN_API USG_Idle : public UObject, public ISocialGroupState public: virtual void ToGazing(ASocialGroup* SG) override; - -}; + +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_InGroup.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_InGroup.h index 751e365af2509d287313e38f00b66f95a9325c12..6d725c37449bdf1b6aef025d7976b4b39692efa3 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_InGroup.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_InGroup.h @@ -15,7 +15,7 @@ UCLASS() class CHARACTERPLUGIN_API USG_InGroup : public UObject, public ISocialGroupState { GENERATED_BODY() - + public: virtual void ToLeaving(ASocialGroup* SG) override; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Leaving.h b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Leaving.h index 0ff2a9edb1639fd1cb9313cc9f1345d8a2419d92..207d6d7ccbacb6b548c652d4320a9a7d36044279 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Leaving.h +++ b/Source/CharacterPlugin/Public/SocialGroups/SocialGroupStates/SG_Leaving.h @@ -18,5 +18,5 @@ class CHARACTERPLUGIN_API USG_Leaving : public UObject, public ISocialGroupState public: virtual void ToIdle(ASocialGroup* SG) override; - -}; + +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/SocialGroups/VHSocialGroups.h b/Source/CharacterPlugin/Public/SocialGroups/VHSocialGroups.h index e2a83788e29c5bb16b3634b31f8a2ff565e5cfef..9ad958907d4dcb7b56196d10d7184d6ee21fc9a3 100644 --- a/Source/CharacterPlugin/Public/SocialGroups/VHSocialGroups.h +++ b/Source/CharacterPlugin/Public/SocialGroups/VHSocialGroups.h @@ -17,8 +17,8 @@ class ASocialGroup; UENUM() enum EGazeStates { - GazeAtSpeaker UMETA(DisplayName = "Gaze at Speaker"), - GazeAtRandom UMETA(DisplayName = "Random Gazing"), + GazeAtSpeaker UMETA(DisplayName = "Gaze at Speaker"), + GazeAtRandom UMETA(DisplayName = "Random Gazing"), }; UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent)) @@ -39,24 +39,25 @@ public: virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; UPROPERTY() - TEnumAsByte<EGazeStates> GazeState; + TEnumAsByte<EGazeStates> GazeState; UFUNCTION(BlueprintCallable) - void LeaveGroup(); + void LeaveGroup(); UFUNCTION(BlueprintCallable) - void JoinGroup(ASocialGroup* SG); - + void JoinGroup(ASocialGroup* SG); + UFUNCTION() - void RandomGazing(); + void RandomGazing(); UFUNCTION() - void OnAudioFinished(); + void OnAudioFinished(); void SetIsSpeaker(const bool bSpeaker) { bIsSpeaker = bSpeaker; } + bool GetIsSpeaker() const { return bIsSpeaker; @@ -76,6 +77,7 @@ public: { return AnimationInstance; } + AVirtualHumanAIController* GetAIController() const { return AIController; @@ -86,32 +88,32 @@ public: void VHMoveToLocation(FVector location, float speed); void SetGazingTimer(); void EndGazing(); - + bool bAudioCanFinish; bool bGazeToUser; - + void StartGazeToUserTimer(); FTimerHandle GazeToUserTimer; void GazeToUser(); void ClearGazeToUserTimer(); -private: +private: APawn* VHPawn; AVirtualHumanAIController* AIController; UCharacterMovementComponent* GetCharacterMovementComponent(); TArray<FVector> PositionsOnCircle; UPROPERTY() - AVirtualHuman* AVirtualHumanPtr; + AVirtualHuman* AVirtualHumanPtr; UPROPERTY() - UVHAnimInstance* AnimationInstance; + UVHAnimInstance* AnimationInstance; FTimerHandle GazingTimerHandle; UPROPERTY() - ASocialGroup* SocialGroup; + ASocialGroup* SocialGroup; UPROPERTY() - UVAAudiofileSourceComponent* AudioComp; + UVAAudiofileSourceComponent* AudioComp; UPROPERTY() - UVHGazing* GazingComp; + UVHGazing* GazingComp; FRandomStream SocialGroupsRandomStream; @@ -124,7 +126,4 @@ private: float CurrentYaw; -}; - - - +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VHAnimInstance.h b/Source/CharacterPlugin/Public/VHAnimInstance.h index 2ddb74aba662eebec0ea43df04c25c99319c80df..fa837eb27de40a13087e67c3d39af5b621a56c1c 100644 --- a/Source/CharacterPlugin/Public/VHAnimInstance.h +++ b/Source/CharacterPlugin/Public/VHAnimInstance.h @@ -12,63 +12,63 @@ UENUM() enum EPointingHand { - HandNone = 0 UMETA(DisplayName = "None"), - HandLeft = 1 UMETA(DisplayName = "Left Hand"), - HandRight = 2 UMETA(DisplayName = "Right Hand") + HandNone = 0 UMETA(DisplayName = "None"), + HandLeft = 1 UMETA(DisplayName = "Left Hand"), + HandRight = 2 UMETA(DisplayName = "Right Hand") }; UCLASS() -class CHARACTERPLUGIN_API UVHAnimInstance : public UAnimInstance { - GENERATED_UCLASS_BODY() +class CHARACTERPLUGIN_API UVHAnimInstance : public UAnimInstance +{ + GENERATED_UCLASS_BODY() public: - // All of these rotations are initially 0 // they are all applied in component space (so relative to the actor's rotation) // our models by default point in positive-y, so for example roll would be nodding // and yaw would be shaking the head - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FRotator SkelControl_Head = FRotator(0.0f, 0.0f, 0.0f); - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FRotator SkelControl_LeftEyeRot = FRotator(0.0f, 0.0f, 0.0f); + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator SkelControl_Head = FRotator(0.0f, 0.0f, 0.0f); - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FRotator SkelControl_RightEyeRot = FRotator(0.0f, 0.0f, 0.0f); + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator SkelControl_LeftEyeRot = FRotator(0.0f, 0.0f, 0.0f); - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FRotator SkelControl_JawRot = FRotator(0.0f, 0.0f, 0.0f); + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator SkelControl_RightEyeRot = FRotator(0.0f, 0.0f, 0.0f); - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FVHGazingData VHGazingData; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator SkelControl_JawRot = FRotator(0.0f, 0.0f, 0.0f); + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVHGazingData VHGazingData; // IK Foot System - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IKOffsetRight; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IKOffsetLeft; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IKHipOffset; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IKFootRotation; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IKOffsetRight; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IKOffsetLeft; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IKHipOffset; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IKFootRotation; - UPROPERTY(VisibleAnywhere, BlueprintReadWrite) - TEnumAsByte<EPointingHand> PointingUseHand = EPointingHand::HandNone; + UPROPERTY(VisibleAnywhere, BlueprintReadWrite) + TEnumAsByte<EPointingHand> PointingUseHand = EPointingHand::HandNone; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FVector EffectorPosition; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector EffectorPosition; // value for the blink blendshapes (0 open eyes, 1 eyes closed) - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float EyeBlink=0; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float EyeBlink = 0; - // this value is 1.0f if DefaultSlot is playing an animation and 0.001f otherwise - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IsDefaultSlotPlayingAnimation = 0.001f; + // this value is 1.0f if DefaultSlot is playing an animation and 0.001f otherwise + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IsDefaultSlotPlayingAnimation = 0.001f; - // this value is 1.0f if CustomIdleSlot is playing an animation and 0.001f otherwise - UPROPERTY(EditAnywhere, BlueprintReadWrite) - float IsCustomIdleSlotPlayingAnimation = 0.001f; + // this value is 1.0f if CustomIdleSlot is playing an animation and 0.001f otherwise + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float IsCustomIdleSlotPlayingAnimation = 0.001f; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VHListenerBackchannels.h b/Source/CharacterPlugin/Public/VHListenerBackchannels.h index 72f6253ddfe4381b150f68556a1586c0bc79a85d..652017480823f7f9f2021905833b5b64d5305be0 100644 --- a/Source/CharacterPlugin/Public/VHListenerBackchannels.h +++ b/Source/CharacterPlugin/Public/VHListenerBackchannels.h @@ -11,12 +11,12 @@ class UVHAnimInstance; -UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class CHARACTERPLUGIN_API UVHListenerBackchannels : public UActorComponent { GENERATED_BODY() -public: +public: UVHListenerBackchannels(); virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; @@ -31,7 +31,7 @@ protected: UPROPERTY(EditAnywhere) float NodAmplitude = 3.0; //degrees - + private: UVHAnimInstance* AnimInstance = nullptr; FRandomStream RandomStream; @@ -40,5 +40,5 @@ private: float NoddingTime; float ActualNodDuration; //duration of one nod float ActualNodAmplitude; - float ActualNodLength;//can be used to play a double nod etc. -}; + float ActualNodLength; //can be used to play a double nod etc. +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VHMovement.h b/Source/CharacterPlugin/Public/VHMovement.h index 400574e678588d5be34b1fdc154c94a62ba815a2..2c27bd19c56a7568679edb1afb174462f132ccdc 100644 --- a/Source/CharacterPlugin/Public/VHMovement.h +++ b/Source/CharacterPlugin/Public/VHMovement.h @@ -37,7 +37,7 @@ public: UVHMovement(); // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, - FActorComponentTickFunction* ThisTickFunction) override; + FActorComponentTickFunction* ThisTickFunction) override; void MoveToWaypoint(const FVector& TargetLocation, const float Speed); void MoveToWaypoint(); @@ -120,7 +120,8 @@ protected: private: float OffsetFromWaypoint; - UPROPERTY() TArray<AWaypoint*> Waypoints; + UPROPERTY() + TArray<AWaypoint*> Waypoints; TMap<AWaypoint*, TArray<FVector>> ChildPoints; const float MAX_WALKING_SPEED = 350.0f; @@ -129,19 +130,26 @@ private: bool bChildMovement; bool bLineMovement; - UPROPERTY() APawn* AVirtualHumanPawn; - UPROPERTY() AVirtualHuman* ParentVH; - UPROPERTY() AVirtualHuman* AVirtualHumanPtr; - UPROPERTY() AVirtualHumanAIController* VirtualHumanAIController; + UPROPERTY() + APawn* AVirtualHumanPawn; + UPROPERTY() + AVirtualHuman* ParentVH; + UPROPERTY() + AVirtualHuman* AVirtualHumanPtr; + UPROPERTY() + AVirtualHumanAIController* VirtualHumanAIController; - UPROPERTY() AWaypoint* CurrentWaypoint; + UPROPERTY() + AWaypoint* CurrentWaypoint; - UPROPERTY() UNavigationPath* NavigationPath; + UPROPERTY() + UNavigationPath* NavigationPath; float IKTraceDistance; bool bWalkingUp; FVector HitLocation; - UPROPERTY() UVHAnimInstance* AnimationInstance; + UPROPERTY() + UVHAnimInstance* AnimationInstance; FRandomStream MovementRandomStream; @@ -183,4 +191,4 @@ private: UFUNCTION(BlueprintCallable) void WaypointMovement(); -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VHPointing.h b/Source/CharacterPlugin/Public/VHPointing.h index 93d7620af1372f579bc7b4f3a31c24600cf9a05c..f849c54164a6b2b5fa2d96fac466c014cb1b450c 100644 --- a/Source/CharacterPlugin/Public/VHPointing.h +++ b/Source/CharacterPlugin/Public/VHPointing.h @@ -8,13 +8,12 @@ #include "VHPointing.generated.h" - -UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class CHARACTERPLUGIN_API UVHPointing : public UActorComponent { GENERATED_BODY() -public: +public: // Sets default values for this component's properties UVHPointing(); @@ -25,7 +24,7 @@ protected: private: UVHAnimInstance* VHAnimInstance; -public: +public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; UPROPERTY(EditAnywhere, BlueprintReadWrite) @@ -35,4 +34,4 @@ public: // Angle of back area at which pointing stops in degrees. UPROPERTY(EditAnywhere, BlueprintReadWrite) float BlindAngle = 30.0; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VirtualHuman.h b/Source/CharacterPlugin/Public/VirtualHuman.h index 057ba269195a0baba9a473c31dca866d91f2e619..c4f781a36b2975d7f7d57e534cc9ac3e2c8f6ebf 100644 --- a/Source/CharacterPlugin/Public/VirtualHuman.h +++ b/Source/CharacterPlugin/Public/VirtualHuman.h @@ -21,12 +21,13 @@ enum class EBodyType : uint8 UENUM() enum class EVHGender : uint8 { - Male UMETA(DisplayName = "Male"), - Female UMETA(DisplayName = "Female"), - Divers UMETA(DisplayName = "Divers"), + Male UMETA(DisplayName = "Male"), + Female UMETA(DisplayName = "Female"), + Divers UMETA(DisplayName = "Divers"), }; -struct BoneNames { +struct BoneNames +{ FName boneroot; FName spine01; @@ -52,7 +53,7 @@ struct BoneNames { FName lowerarm_l; FName hand_r; FName hand_l; - + FName pelvis; FName calf_r; FName calf_l; @@ -66,6 +67,7 @@ struct BoneNames { }; class UVHAnimInstance; + UCLASS() class CHARACTERPLUGIN_API AVirtualHuman : public ACharacter { @@ -95,7 +97,7 @@ public: UFUNCTION(BlueprintCallable) virtual EVHGender GetGender(); virtual bool SupportsMorphs(); - + /** * Forces a new IDLE animation to be played, which is randomly chosen from "CustomIdleAnimations". * Note that the new animation might also be the one which is currently playing. @@ -130,7 +132,6 @@ protected: float MinBlendTime = 1.0; private: - BoneNames BoneNames; bool bFirstTick = true; @@ -150,5 +151,5 @@ private: virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; #endif virtual void OnConstruction(const FTransform& Transform) override; - + }; \ No newline at end of file diff --git a/Source/CharacterPlugin/Public/VirtualHumanAIController.h b/Source/CharacterPlugin/Public/VirtualHumanAIController.h index dcca9b0ca025bdc2f46a3771e13edab42ba34f17..7cea1067cfed549dbea506f139c76931963c9453 100644 --- a/Source/CharacterPlugin/Public/VirtualHumanAIController.h +++ b/Source/CharacterPlugin/Public/VirtualHumanAIController.h @@ -27,7 +27,6 @@ public: void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) override; private: - TArray<AVHsManager*> GetAssociatedVHsManagers(); float LastDeltaTime = 0.0f; diff --git a/Source/CharacterPlugin/Public/Waypoint.h b/Source/CharacterPlugin/Public/Waypoint.h index bd27d3d23dad31243cd389883fc46557a08c8b45..e1ace22ca7a1c775a5b03368bdad42b30a8e2b36 100644 --- a/Source/CharacterPlugin/Public/Waypoint.h +++ b/Source/CharacterPlugin/Public/Waypoint.h @@ -9,34 +9,34 @@ UENUM() enum EOnWaypointReach { - Stay UMETA(DisplayName = "Stationary Agent"), - Destroy UMETA(DisplayName = "Destroy Agent"), + Stay UMETA(DisplayName = "Stationary Agent"), + Destroy UMETA(DisplayName = "Destroy Agent"), }; UCLASS() class CHARACTERPLUGIN_API AWaypoint : public AStaticMeshActor { GENERATED_BODY() + public: AWaypoint(); - int GetWaypointOrder() const; + int GetWaypointOrder() const; float GetWalkingSpeed() const; int GetWaypointGroup() const; int GetLastWaypointCommand() const; - + private: - UPROPERTY(EditAnywhere, meta = (AllowPrivateAccess = "true")) int WaypointOrder; UPROPERTY(EditAnywhere, meta = (AllowPrivateAccess = "true", ClampMin = "0.0", ClampMax = "350.0", UIMin = "0.0", UIMax = "350.0")) float WalkingSpeed; - + /* * Specify to which VA the waypoint belongs to. * This waypoint belongs to all VAs, that are in the same WaypointGroup. */ - UPROPERTY(EditAnywhere,BlueprintReadWrite, meta = (AllowPrivateAccess = "true")) + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true")) int WaypointGroup; /* @@ -45,4 +45,4 @@ private: */ UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true")) TEnumAsByte<EOnWaypointReach> OnReachLastWaypoint = EOnWaypointReach::Destroy; -}; +}; \ No newline at end of file diff --git a/Source/CharacterPluginEditor/CharacterPluginEditor.Build.cs b/Source/CharacterPluginEditor/CharacterPluginEditor.Build.cs index e01da0dab3bef466399a54499d952ed1bd82f0ef..fdc10c50ee0bf4b6407f62885d56dc6b9dda2d06 100644 --- a/Source/CharacterPluginEditor/CharacterPluginEditor.Build.cs +++ b/Source/CharacterPluginEditor/CharacterPluginEditor.Build.cs @@ -3,15 +3,17 @@ using System.IO; public class CharacterPluginEditor : ModuleRules { - public CharacterPluginEditor(ReadOnlyTargetRules Target) : base(Target) - { + public CharacterPluginEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; - PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + PrivateIncludePaths.AddRange(new string[] { }); + PublicIncludePaths.AddRange(new string[] { }); - PrivateIncludePaths.AddRange(new string[] { }); - PublicIncludePaths.AddRange(new string[] { }); - - PublicDependencyModuleNames.AddRange(new string[] { "CoreUObject", "Engine", "Core", "DisplayCluster", "AIModule", "Projects", "NavigationSystem", "AIModule", "UniversalLogging", "AnimGraph", "AnimGraphRuntime", "BlueprintGraph", "CharacterPlugin" }); - - } + PublicDependencyModuleNames.AddRange(new string[] + { + "CoreUObject", "Engine", "Core", "DisplayCluster", "AIModule", "Projects", "NavigationSystem", "AIModule", + "UniversalLogging", "AnimGraph", "AnimGraphRuntime", "BlueprintGraph", "CharacterPlugin" + }); + } } \ No newline at end of file diff --git a/Source/CharacterPluginEditor/Private/AnimGraphNode_VHGazing.cpp b/Source/CharacterPluginEditor/Private/AnimGraphNode_VHGazing.cpp index 9733d766bf439fafaaecd39e1ad7082fd05a6bf1..13a81f26014b5ac5d746338ca8e7b12ddc6a8dd2 100644 --- a/Source/CharacterPluginEditor/Private/AnimGraphNode_VHGazing.cpp +++ b/Source/CharacterPluginEditor/Private/AnimGraphNode_VHGazing.cpp @@ -6,9 +6,7 @@ #define LOCTEXT_NAMESPACE "AnimNodes" UAnimGraphNode_VHGazing::UAnimGraphNode_VHGazing(const FObjectInitializer& ObjectInitializer) - :Super(ObjectInitializer) -{ -} + : Super(ObjectInitializer) {} FLinearColor UAnimGraphNode_VHGazing::GetNodeTitleColor() const { @@ -30,4 +28,4 @@ FString UAnimGraphNode_VHGazing::GetNodeCategory() const return TEXT("CharacterPlugin"); } -#undef LOCTEXT_NAMESPACE +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Source/CharacterPluginEditor/Private/CharacterPluginEditor.cpp b/Source/CharacterPluginEditor/Private/CharacterPluginEditor.cpp index 5cd77f2b27634ac56deda3d62e434bad8125d331..cd771a554a46d874ea2f8f31c4f64d8982222110 100644 --- a/Source/CharacterPluginEditor/Private/CharacterPluginEditor.cpp +++ b/Source/CharacterPluginEditor/Private/CharacterPluginEditor.cpp @@ -2,14 +2,8 @@ #define LOCTEXT_NAMESPACE "FCharacterPluginEditorModule" -void FCharacterPluginEditorModule::StartupModule () -{ - -} -void FCharacterPluginEditorModule::ShutdownModule() -{ - -} +void FCharacterPluginEditorModule::StartupModule() {} +void FCharacterPluginEditorModule::ShutdownModule() {} #undef LOCTEXT_NAMESPACE diff --git a/Source/CharacterPluginEditor/Private/ModifyCurvesGraphNode.cpp b/Source/CharacterPluginEditor/Private/ModifyCurvesGraphNode.cpp index 18d5e3e637052e437e5893a5717ba8a95797e35b..739a2d9f83094d818fe83d5458e432c5971bac42 100644 --- a/Source/CharacterPluginEditor/Private/ModifyCurvesGraphNode.cpp +++ b/Source/CharacterPluginEditor/Private/ModifyCurvesGraphNode.cpp @@ -6,9 +6,7 @@ #define LOCTEXT_NAMESPACE "AnimNodes" UModifyCurvesGraphNode::UModifyCurvesGraphNode(const FObjectInitializer& ObjectInitializer) - :Super(ObjectInitializer) -{ -} + : Super(ObjectInitializer) {} FLinearColor UModifyCurvesGraphNode::GetNodeTitleColor() const { @@ -30,4 +28,4 @@ FString UModifyCurvesGraphNode::GetNodeCategory() const return TEXT("CharacterPlugin"); } -#undef LOCTEXT_NAMESPACE +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Source/CharacterPluginEditor/Public/AnimGraphNode_VHGazing.h b/Source/CharacterPluginEditor/Public/AnimGraphNode_VHGazing.h index 609b7abe46217e66af801e68a3b3e9de6d8a99c9..043b1475bc2b7bef8b26821b66bcb9df872b71b9 100644 --- a/Source/CharacterPluginEditor/Public/AnimGraphNode_VHGazing.h +++ b/Source/CharacterPluginEditor/Public/AnimGraphNode_VHGazing.h @@ -13,12 +13,11 @@ UCLASS() class CHARACTERPLUGINEDITOR_API UAnimGraphNode_VHGazing : public UAnimGraphNode_Base { GENERATED_BODY() - + UPROPERTY(EditAnywhere, Category = Settings) FAnimNode_VHGazing Node; public: - virtual FLinearColor GetNodeTitleColor() const override; virtual FText GetTooltipText() const override; virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; @@ -28,5 +27,5 @@ public: UAnimGraphNode_VHGazing(const FObjectInitializer& ObjectInitializer); protected: - -}; + +}; \ No newline at end of file diff --git a/Source/CharacterPluginEditor/Public/CharacterPluginEditor.h b/Source/CharacterPluginEditor/Public/CharacterPluginEditor.h index 0e19bf0651ba8e9e91495318eae49b8e29b6f143..f3cd36396575f1c31a9e18bac377f4b7e6b15687 100644 --- a/Source/CharacterPluginEditor/Public/CharacterPluginEditor.h +++ b/Source/CharacterPluginEditor/Public/CharacterPluginEditor.h @@ -6,6 +6,6 @@ class FCharacterPluginEditorModule : public IModuleInterface { public: - virtual void StartupModule () override; - virtual void ShutdownModule() override; -}; + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; \ No newline at end of file diff --git a/Source/CharacterPluginEditor/Public/ModifyCurvesGraphNode.h b/Source/CharacterPluginEditor/Public/ModifyCurvesGraphNode.h index 5b16960d8c6fa81b1624707739539bdfd3b56cf7..cbc3d538fd8a3b83430a573100ea0b46dd181fc7 100644 --- a/Source/CharacterPluginEditor/Public/ModifyCurvesGraphNode.h +++ b/Source/CharacterPluginEditor/Public/ModifyCurvesGraphNode.h @@ -13,12 +13,11 @@ UCLASS() class CHARACTERPLUGINEDITOR_API UModifyCurvesGraphNode : public UAnimGraphNode_Base { GENERATED_BODY() - + UPROPERTY(EditAnywhere, Category = Settings) FModifyCurvesNode Node; public: - virtual FLinearColor GetNodeTitleColor() const override; virtual FText GetTooltipText() const override; virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; @@ -28,5 +27,5 @@ public: UModifyCurvesGraphNode(const FObjectInitializer& ObjectInitializer); protected: - -}; + +}; \ No newline at end of file