https://github.com/gustavomagallanesguijon/shoal_VR
Raw File
Tip revision: 67e727bd7c730a38f1c7625dbe94539e55fa86f3 authored by Gustavo Magallanes Guijón on 20 September 2018, 17:43:47 UTC
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);
}
back to top