https://github.com/gustavomagallanesguijon/shoal_VR
Tip revision: 67e727bd7c730a38f1c7625dbe94539e55fa86f3 authored by Gustavo Magallanes Guijón on 20 September 2018, 17:43:47 UTC
corregi Pez.h
corregi Pez.h
Tip revision: 67e727b
PezState.cpp~
/*=================================================
* FileName: PezState.cpp
*
* Created by: Gustavo Magallanes Guijón
* Project name: Cardumen
* Unreal Engine version: 4.19.1
* Created on: 2018/04/17
*
* =================================================*/
#include "PezState.h"
#include "Pez.h"
void SeekState::Update(float delta)
{
Fish->isFleeing = false;
Fish->fleeTarget = NULL;
Fish->preyTarget = NULL;
if (Fish->isLeader)
{
// Seek target
SeekTarget(delta);
}
else
{
// School with buddies
Flock(delta);
}
}
void SeekState::SeekTarget(float delta)
{
// Set Speed
Fish->curSpeed = FMath::Lerp(Fish->curSpeed, Fish->speed, delta * Fish->SeekDecelerationMultiplier);
// Set Rotation
FVector targetRotation = (Fish->getSeekTarget() - Fish->GetActorLocation() + Fish->AvoidObstacle());
FRotator leaderRotation = FRotationMatrix::MakeFromX(targetRotation).Rotator();
leaderRotation = FMath::RInterpTo(Fish->GetActorRotation(), leaderRotation, delta, Fish->turnSpeed);
Fish->setRotation(leaderRotation);
// Set Velocity Vector
FVector leaderVelocity = Fish->GetActorForwardVector() * (delta * Fish->curSpeed);
Fish->setVelocity(leaderVelocity);
}
void SeekState::Flock(float delta)
{
// Get a list of Fish neighbors and calculate seperation
FVector seperation = FVector(0, 0, 0);
if (Fish->nearbyFriends.IsValidIndex(0))
{
TArray<AActor*> neighborList = Fish->nearbyFriends;
int neighborCount = 0;
for (int i = 0; i < Fish->nearbyFriends.Num(); i++)
{
if (neighborList.IsValidIndex(i))
{
seperation += neighborList[i]->GetActorLocation() - Fish->GetActorLocation();
neighborCount++;
}
if (i == Fish->NumNeighborsToEvaluate && i != 0)
{
break;
}
}
seperation = ((seperation / neighborCount) * -1);
seperation.Normalize();
seperation *= Fish->neighborSeperation;
}
// Maintain distance behind Leader
FVector distBehind = (Cast<APez>(Fish->leader)->getVelocity() * -1);
distBehind.Normalize();
distBehind *= Fish->followDist;
// Calculate all seperation and distance behind leader into one vector
FVector leaderLocation = Fish->leader->GetActorLocation();
FVector flockerVelocity = distBehind + leaderLocation + seperation + Fish->AvoidObstacle();
FRotator flockerRotation = FRotationMatrix::MakeFromX(flockerVelocity - Fish->GetActorLocation()).Rotator();
// If fish is too far behind leader, speed up
float newSpeed = Fish->speed;
if (Fish->GetDistanceTo(Fish->leader) > Fish->distBehindSpeedUpRange)
{
// Set Speed
Fish->curSpeed = FMath::Lerp(Fish->curSpeed, Fish->maxSpeed, delta);
}
else
{
// Set Speed
Fish->curSpeed = FMath::Lerp(Fish->curSpeed, Fish->speed, delta);
}
// Set Velocity
FVector flockVelocity = Fish->GetActorForwardVector() * (delta * Fish->curSpeed);
Fish->setVelocity(flockVelocity);
// Set Rotation
FRotator flockRotation = FMath::RInterpTo(Fish->GetActorRotation(), flockerRotation, delta, Fish->turnSpeed);
Fish->setRotation(flockRotation);
}
void FleeState::Update(float delta)
{
Fish->isFleeing = true;
Fish->fleeTarget = Enemy;
Fish->preyTarget = NULL;
if (Fish->GetDistanceTo(Enemy) >= Fish->fleeDistance)
{
Fish->setState(new SeekState(Fish));
}
FleeFromEnemy(delta);
}
void FleeState::FleeFromEnemy(float delta)
{
// Set Speed
Fish->curSpeed = FMath::Lerp(Fish->curSpeed, Fish->maxSpeed, (delta * Fish->FleeAccelerationMultiplier));
// Set Velocity
FVector fleeVelocity = Fish->GetActorForwardVector() * (delta * Fish->curSpeed);
Fish->setVelocity(fleeVelocity);
// Set Rotation
FVector targetRotation = (Fish->GetActorLocation() - Enemy->GetActorLocation()) + Fish->AvoidObstacle();
FRotator fleeRotation = FRotationMatrix::MakeFromX(targetRotation).Rotator();
fleeRotation = FMath::RInterpTo(Fish->GetActorRotation(), fleeRotation, delta, Fish->turnSpeed);
Fish->setRotation(fleeRotation);
}
void ChaseState::Update(float delta)
{
Fish->isFleeing = false;
Fish->fleeTarget = NULL;
Fish->preyTarget = Prey;
EatPrey();
ChasePrey(delta);
}
void ChaseState::EatPrey()
{
if (Fish->GetDistanceTo(Prey) < 1000)
{
float zLoc = Fish->minZ + FMath::Abs(0.25 * Fish->maxZ);
Prey->SetActorLocation(FVector(FMath::FRandRange(Fish->minX, Fish->maxX), FMath::FRandRange(Fish->minY, Fish->maxX), zLoc));
Fish->isFull = true;
Fish->setState(new SeekState(Fish));
}
}
void ChaseState::ChasePrey(float delta)
{
// Set Speed
Fish->curSpeed = FMath::Lerp(Fish->curSpeed, Fish->maxSpeed, (delta * Fish->ChaseAccelerationMultiplier));
// Set Velocity
FVector chaseVelocity = Fish->GetActorForwardVector() * (delta * Fish->curSpeed);
Fish->setVelocity(chaseVelocity);
// Set Rotation
FVector seperation = FVector(0, 0, 0);
if (Fish->nearbyFriends.IsValidIndex(0))
{
int neighborCount = 0;
TArray<AActor*> neighborList = Fish->nearbyFriends;
for (int i = 0; i < Fish->NumNeighborsToEvaluate; i++)
{
if (neighborList.IsValidIndex(i))
{
seperation += neighborList[i]->GetActorLocation() - Fish->GetActorLocation();
neighborCount++;
}
}
seperation = ((seperation / neighborCount) * -1);
seperation.Normalize();
seperation *= Fish->neighborSeperation;
}
FVector preyLocation = Prey->GetActorLocation();
FVector flockerVelocity = ((preyLocation + seperation) - Fish->GetActorLocation()) + Fish->AvoidObstacle();
FRotator flockerRotation = FRotationMatrix::MakeFromX(flockerVelocity).Rotator();
FRotator chaseRotation = FMath::RInterpTo(Fish->GetActorRotation(), flockerRotation, delta, Fish->turnSpeed);
Fish->setRotation(chaseRotation);
}