Gemrock

Gemrock puts you in control of Rockhead, a small earthen creature filled with magical life to find out why the old energies are about to to be corrupted. Discover beautiful luminous caves with a dense atmosphere in the underground, while you (almost) die and die again. As you explore, you'll find radiant gems, granting you powerful abilities to delve deeper into the caves and your full potential to exploit.
My biggest task here was to create a flocking system script that should allow us Controlling a flock of gems in order to manipulate certain objects.



My tasks:

-Gameplay Programmer: Player Controller and Flocking system.

Download-Link: Gemrock


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Flocking : MonoBehaviour {

	//Player Script
	SSPlayerController Player;
	//Player Collider
	GameObject Playercollid;
	//The Speed which the Birbs start with
	public float Speedx = 1f;
	public float Speedy = 1f;
	//Radius which the Birbs avoid the player
	float Radius = 1f;
	//Rotation Speed of the birbs
	float RotationSpeed = 4.0f;
	//The Avoid Vector and Diretion Vector of the birbs
	Vector3 Avoid;
	Vector3 Direction;
	//The Distance which a nighbour can have to be in a group
	float NighbourDistance = 4f;
	//bool to check if the birb needs to turnaround
	bool Turning = false;

	// Use this for initialization
	void Start ()
	{
		Player = GameObject.FindWithTag("Player").GetComponent();
		Playercollid = GameObject.FindWithTag("Model");
		//Speed get a Random number
		Speedx = Random.Range(0.5f, 10f);
		Speedy = Random.Range(0.5f, 10f);
		//Because the birbs are to slow to avoid the player in time they additionally ignore the players collider
		Physics.IgnoreCollision(gameObject.GetComponent(), Playercollid.GetComponent());
		Physics.GetIgnoreLayerCollision(1,1);
	}
	
	// Update is called once per frame
	void FixedUpdate ()
	{
		//Checking if the player is in the radius to avoid and let the avoid if he is
		if(Vector3.Distance(Player.transform.position, transform.position) <= Radius)
		{
			Avoid = Player.transform.position - transform.position;
			Direction = CrystallController.Pos - Avoid;            
		}
		else
		{
			Direction = (CrystallController.Pos - transform.position).normalized;
		}
		/*Checking the distance between the flocking controller and the birbs 
		and let the turn back to the controller if it's needed*/
		if (Vector3.Distance(transform.position, CrystallController.Pos) >= GlobalFlock.Distance)
		{
			Turning = true;
		}
		else
		{
			Turning = false;
		}
		/*This is the Turning rule. if its true the birbs went turn the direction 
		to the Controller also here we set the speed for the x- and y-axis to a 
		new random number and also looking for a smooth y-axis move*/
		if (Turning)
		{
				transform.rotation = Quaternion.Slerp(transform.rotation,
													  Quaternion.LookRotation(Direction),
													  RotationSpeed);
			Speedx = Random.Range(1f, 5);
			int Rand = Random.Range(0, 2);
			if (Rand == 1)
			{
				Speedy = Random.Range(1f, 5);
			}
			else
			{
				Speedy = Random.Range(-1f, -5);
			}
		}
		//If the turning is not needed we cheeck if we can start a Rule for the Birb group
		else
		{
			if (Random.Range(0, 5) < 1)
			{
				ApplyRules();
			}
		}
		//That we have the Birbs moving fast enough for the Controller move
		if(CrystallController.Move == true)
		{
			Speedx = 5;
			Speedy = 5;
		}
		//Birbs movement speed in the idle position
		transform.Translate(0, (Speedy * Time.deltaTime) , Speedx * Time.deltaTime);
		}
		//Here we Define the rule for the behavior in a group
		void ApplyRules()
		{
		//Create an array with the birbs that existing
		GameObject[] gos;
		gos = GlobalFlock.AllCrystal;
		/*Set up new Vectors that are only avaiable 
		  in the rule and setting them*/
		Vector3 VCentre = Vector3.zero;
		Vector3 VAvoid = Vector3.zero;
		Vector3 GoalPos = GlobalFlock.GoalPos;
		//Also for the speed
		float gSpeedx = 0.5f;
		float gSpeedy = 0.5f;
		//A float to store Distance between two gameobject
		float Dist;
		//a int to store the Group size
		int GroupSize = 0;
		//Loop to get the group size and let them avoid each other if needed
		foreach(GameObject go in gos)
		{
			if(go != this.gameObject)
			{
				Dist = Vector3.Distance(go.transform.position, this.transform.position);
				if(Dist <= NighbourDistance)
				{
					GroupSize++;
					if(Dist < 1.0f)
					{
						VAvoid = VAvoid + (this.transform.position - go.transform.position);
					}
					Flocking anotherFlock = go.GetComponent();
					gSpeedx = gSpeedx + anotherFlock.Speedx;
					gSpeedy = gSpeedy + anotherFlock.Speedy;
				}
			}
			if(Vector3.Distance(Player.transform.position, this.transform.position) <= Radius)
			{
				VAvoid =(this.transform.position - Player.transform.position).normalized;
			}
			VCentre += (go.transform.position + VAvoid).normalized;
		}
		//the behavior in a group
		if(GroupSize > 0)
		{
			VCentre = VCentre / GroupSize + (GoalPos - this.transform.position);
			Speedx = gSpeedx / GroupSize;
			Speedy = gSpeedy / GroupSize;
			Vector3 Direction = (VCentre + VAvoid).normalized - transform.position;
			if(Direction != Vector3.zero)
			{
				transform.rotation = Quaternion.Slerp(transform.rotation,
													  Quaternion.LookRotation(Direction),
													  RotationSpeed * Time.deltaTime);
			}
		}
	}
}