/* * FUNCTION: * This script generates obstacles, currency units and powerups on every patch. * The spline is used to ensure obstacles are created after regular distances. The start of * the spline is 0.0 and the end is 1.0. * * USED BY: * This script is a part of the "Player" prefab. * */ using System; using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; using Random = UnityEngine.Random; public class ElementsGeneratorCS : MonoBehaviour { public enum ElementType { SingleLaneObstacle = 0, MultiLaneObstacle = 1, Currency = 3, Powerup = 4, Null = 5, Destroyable = 6, Prize } public bool Spawnprize; //properties of elements (obstacles, powerups, currency) private struct Element { public Transform[] tPrefabHandle;//array of clones of a particular element public int iFrequency; //frequency of occurance of a particular element public ElementType elementType; public int iPrefabHandleIndex;//element clone currently in use } public GameObject[] obstaclePrefabs;//prefabs of obstacles public GameObject[] powerupPrefabs; //prefabs of powerups public GameObject currencyPrefab; //prefab of currency public GameObject superPrize;//prefabSuperPrize public GameObject Letter;//prefabSuperPrize private Element[] elements; //class array private Transform tPrefabHandlesParent;//holds all instances of element clones private int iObstacleCount;//total number obstacles private int iPowerupCount; //total number of powerups private int iTotalCount; //total count of all elements handled by this script public int CounterCurrency; //script references private PowerupsMainControllerCS hPowerupsMainControllerCS; private CheckPointsMainCS hCheckPointsMainCS; private PatchesRandomizerCS hPatchesRandomizerCS; public float fDefaultIncrement = 0.02f;//the default gap between obstacles public int iLastPowerupGenerated = 0; //how many patches have been generated without a powerup private int iForcePowerupGeneration = 1; //force powerup generation after how many patches private bool bPowerupPlaced = false; //force only a single powerup at a time public int LastOrc; /* * FUNCTION: Tell the randomiser to generate obstacles on newly created patch * CALLED BY: PatchesRandomizer.createNewPatch() */ public bool bGenerateElements; //flag the script to generate elements on next patch public bool GetGift; private int _magnetismIndex = 0; private int _sledgeIndex = 0; private int _lastPowerUp = 0; public bool SpawnLetter; public void generateElements() { bGenerateElements = true; } private bool FirstPlay { get { return GameObject.Find("InfinitelyTraining") || InstructionsHomeButtonHandler.FirstPlay; } } public void Start() { curSpawnCoupone = Random.Range(150, 160); iObstacleCount = obstaclePrefabs.Length; iPowerupCount = powerupPrefabs.Length; iTotalCount = iObstacleCount + iPowerupCount + 1;//obstacles + powerups + currency //bGenerateElements = false; //bPowerupPlaced = true;//do not place powerup on first patch System.DateTime dt = System.DateTime.Now; Random.seed = dt.Hour * dt.Minute * dt.Second; setPrefabHandlers(); //StartCoroutine(SetPrefabHandler()); hPowerupsMainControllerCS = (PowerupsMainControllerCS)this.GetComponent(typeof(PowerupsMainControllerCS)); hCheckPointsMainCS = (CheckPointsMainCS)GameObject.Find("Player").GetComponent(typeof(CheckPointsMainCS)); hPatchesRandomizerCS = (PatchesRandomizerCS)this.GetComponent(typeof(PatchesRandomizerCS)); //generate elements on first patch //GetGift = true; //if (!Tutor.TutorPassed) //{ // Tutor.ActivateColliders(); // //Debug.Log("HERE!!!"); // //generateElements(1, 0.15f, true, 2, 0, 1); // //generateElements(7, 0.15f, true, 0, 0, 1); // //generateElements(1, 0.25f, true, 2, 0, 1); // //generateElements(0, 0.35f, true, 0, 0, 1); // // generateElements(5, 0.50f, true, 0, 0, 1); // // generateElements(5, 0.50f, true, 1, 0, 1); // // generateElements(5, 0.50f, true, 2, 0, 1); // // generateElements(6, 0.65f, true, 0, 0, 1); // // generateElements(6, 0.65f, true, 1, 0, 1); // // generateElements(6, 0.65f, true, 2, 0, 1); //} }//end of Start() private IEnumerator SetPrefabHandler() { yield return new WaitForSeconds(2); setPrefabHandlers(); } public void ResetElemensForScene() { //Destroy(GameObject.Find("PFHandlesGroup").gameObject); var gos = GameObject.Find("PFHandlesGroup").gameObject.GetComponentsInChildren(); //Debug.Log(gos.Count()); for (int i = 0; i < gos.Count(); i++) { if (gos[i].name != "PFHandlesGroup") { Destroy(gos[i].gameObject); } } curSpawnCoupone = Random.Range(50, 100); iObstacleCount = obstaclePrefabs.Length; iPowerupCount = powerupPrefabs.Length; iTotalCount = iObstacleCount + iPowerupCount + 1;//obstacles + powerups + currency //bGenerateElements = false; //bPowerupPlaced = true;//do not place powerup on first patch System.DateTime dt = System.DateTime.Now; Random.seed = dt.Hour * dt.Minute * dt.Second; //Start(); setPrefabHandlers(); //bGenerateElements = true; //StartGenerateElement(); //bGenerateElements = true; foreach (var lat in ListLetters) { Destroy(lat); } ListLetters.Clear(); } public void StartGenerateElement() { //Debug.Log("Generate"); for (int j = 0; j < 2; j++) { float i = 0.1f; while (i < 0.9f) { int element = getRandomElement(); //while (true) //{ // element = getRandomElement(); // if (element == 5) // { // continue; // } // else // { // break; // } // if (element == 5) // { // if (LastOrc < 10) // { // continue; // } // LastOrc = 0; // break; // } // LastOrc++; // /*if (LastOrc > 20) // { // element = 5; // LastOrc = 0; // }*/ // break; //} float incrementValue = 0f; if (j == 1) { incrementValue = generateElements(element, i, false);//get any type of element } else { incrementValue = generateElements(element, i, true);//get any type of element } //Debug.Log(incrementValue); i += incrementValue; }//end of while } } public List ListLetters; void FixedUpdate() { if (bGenerateElements) { bGenerateElements = false; bPowerupPlaced = false;//place powerup on current patch if randomised iLastPowerupGenerated++;//count how many patches have passed without a power-up StartCoroutine(generateElementsCoroutine()); }//end of if }//end of Update public int j=0; private IEnumerator generateElementsCoroutine() { //Debug.LogError("Generate"); float i = 0.16f; while (i < 0.9) { yield return new WaitForFixedUpdate(); if (i >= 0.1f) { int element = getRandomElement(); float incrementValue = generateElements(element, i, false); //get any type of element //Debug.Log("generateElements !!! " + incrementValue); i += incrementValue; } else { i += 0.03f; } }//end of while StopCoroutine("generateElementsCoroutine"); } /* * FUNCITON: Generate random elements and group of elements. * PARAMETER 1: Element to generate. * PARAMETER 2: Where to generate based on the spline. * PARAMETER 3: If the patch is the starting patch or the next patch generated. */ public int curSpawnCoupone; public bool couponeSending; private float generateElements(int elementNumber, float fLocation, bool bStartPatch, int exactlyPosX = -1, int exactlyPosY = -1, int exactlyCount = -1) { Vector3 v3Position = new Vector3(); //position to put the obstacle on RaycastHit hitInfo; //check y-axis location float CurrentAngle; //billboard the obstacle towards the player float fDefaultDisplacementValue = 15; float fDisplacement = fDefaultDisplacementValue; //horizontal displacement //if obstacle only covers one lane generate a random number of instances of the //obstacle on random locations within a particular radius //Debug.Log(elements[elementNumber].elementType + " bStartPatch " + bStartPatch); if (elements[elementNumber].elementType == ElementType.SingleLaneObstacle) { for (int i = 0; i < (exactlyCount == -1 ? Random.Range(2, 9) : exactlyCount); i++) { //pick where to generate obstacle horizontally on path int iLane = exactlyPosX == -1 ? Random.Range(0, 3) : exactlyPosX; if (iLane == 0) fDisplacement = Mathf.Abs(fDefaultDisplacementValue); else if (iLane == 1) fDisplacement = -Mathf.Abs(fDefaultDisplacementValue); else fDisplacement = 0; //pick where to generate obstacle vertically on path int iVerticalPosition = exactlyPosY == -1 ? Random.Range(0, 3) : exactlyPosY; if (iVerticalPosition == 0) { v3Position = getPosition(fLocation+fDefaultIncrement, bStartPatch); hitInfo = getHitInfo(v3Position); } else if (iVerticalPosition == 1) { v3Position = getPosition(fLocation+(fDefaultIncrement*2), bStartPatch); hitInfo = getHitInfo(v3Position); } else { v3Position = getPosition(fLocation, bStartPatch); hitInfo = getHitInfo(v3Position); } if (fLocation >= 1.0)//dont create obstacles on next patch continue; v3Position.z += fDisplacement; v3Position.y = hitInfo.point.y; CurrentAngle = -hCheckPointsMainCS.getWaypointAngle(); instantiateElement(elementNumber, v3Position, CurrentAngle, hitInfo.normal); } fLocation = fDefaultIncrement*3; } //if the randomised element is currency generate three or more currency units together in a particular lane //also generate single lane obstacles on the lanes without the currency else if (elements[elementNumber].elementType == ElementType.Currency || elements[elementNumber].elementType == ElementType.Powerup) { float[] fObstacleDisplacement = new float[2];//horizontal displacement of obstacles that will be created along currency //pick the lane where to generate currency int iCurrencyLane = UnityEngine.Random.Range(0,3); // Debug.Log(iCurrencyLane); if (iCurrencyLane == 0) { fDisplacement = Mathf.Abs(fDefaultDisplacementValue); fObstacleDisplacement[0] = 0; fObstacleDisplacement[1] = -Mathf.Abs(fDefaultDisplacementValue); } else if (iCurrencyLane == 1) { fDisplacement = -Mathf.Abs(fDefaultDisplacementValue); fObstacleDisplacement[0] = Mathf.Abs(fDefaultDisplacementValue); fObstacleDisplacement[1] = 0; } else { fDisplacement = 0; fObstacleDisplacement[0] = -Mathf.Abs(fDefaultDisplacementValue); fObstacleDisplacement[1] = Mathf.Abs(fDefaultDisplacementValue); } int iToGenerate = Random.Range(3,5);//amount of currency units to generate //Debug.Log(iToGenerate); for (int i=0; i 10 && SpawnLetter && !TooltipLastterController.Instance.WordDone && !LoginManager.Instance.OVERGAME) { var p = (GameObject)Instantiate(Letter, v3Position, Quaternion.identity); SpawnLetter = false; var pText = p.GetComponentInChildren(); ListLetters.Add(p); pText.RenderText = TooltipLastterController.Instance.GetNextLetter(); } else { //Debug.Log(elementNumber); instantiateElement(elementNumber, v3Position, CurrentAngle, hitInfo.normal); //Debug.Log(v3Position); } //int parallelElement = getRandomElement(); int parallelElement = 0; if (elements[elementNumber].elementType == ElementType.Powerup) { while (true) { parallelElement = getRandomElement(); if (parallelElement != 5) { break; } else { // Debug.Log(elements[parallelElement].tPrefabHandle[0].name); } } if (elements[parallelElement].elementType != ElementType.MultiLaneObstacle) { v3Position = getPosition(fLocation, bStartPatch); v3Position.z += fObstacleDisplacement[Random.Range(0, fObstacleDisplacement.Length)]; hitInfo = getHitInfo(v3Position); v3Position.y = hitInfo.point.y; CurrentAngle = -hCheckPointsMainCS.getWaypointAngle(); instantiateElement(parallelElement, v3Position, CurrentAngle, hitInfo.normal); } } fLocation += 0.010f; if (fLocation >= 1.0f) break; } fLocation = iToGenerate*0.010f; } //if the obstacle randomised covers multiple lanes, generate it and move on else if (elements[elementNumber].elementType == ElementType.MultiLaneObstacle) { v3Position = getPosition(fLocation, bStartPatch); hitInfo = getHitInfo(v3Position); v3Position.y = hitInfo.point.y; CurrentAngle = -hCheckPointsMainCS.getWaypointAngle(); instantiateElement(elementNumber, v3Position, CurrentAngle, hitInfo.normal); fLocation = 0.05f; } return fLocation; }//end of instantiate by number /* * FUNCTION: Transfroms the location on spline (0.0 to 1.0) to a Vector3 position * PARAMETER 1: Position on spline (0.0 to 1.0) * PARAMETER 2: Is the patch the first or consecutive generated ones */ private Vector3 getPosition(float fLocation, bool bStartPatch) { if (bStartPatch == true) { return hCheckPointsMainCS.getCurrentWSPointBasedOnPercent(fLocation); } else { return hCheckPointsMainCS.getNextWSPointBasedOnPercent(fLocation); } } /* * FUNCTION: Calculate vertical position to put the element on * PARAMETER 1: The Vector3 position where the element will be placed. * RETURNS: The Raycast hit information. */ private RaycastHit getHitInfo(Vector3 v3Position) { //Raycast towards the ground to check if terrain present bool Groundhit = false; RaycastHit hitInfo; Vector3 DownPos = new Vector3(0,-100,0) + v3Position; var layerMask = 1<<9; Groundhit = Physics.Linecast(v3Position + new Vector3(0,100,0),DownPos, out hitInfo,layerMask); return hitInfo; } /* * FUNCTION: Place element on the required position. * PARAMETER 1: The obstacle, currency unit or powerup to instantiate. * PARAMETER 2: The position where to place the element. * PARAMETER 3: The angle of the element which is based on path's curve. * PATAMETER 4: The Raycast hit information which is based on the element's placement position. */ private void instantiateElement(int elementNumber, Vector3 v3Position, float CurrentAngle, Vector3 hitInfoNormal) { if (elementNumber < 0) return; Transform ObjectHandle; if (elementNumber < iObstacleCount)//obstacles { ObjectHandle = elements[elementNumber].tPrefabHandle[elements[elementNumber].iPrefabHandleIndex]; elements[elementNumber].iPrefabHandleIndex++; if (elements[elementNumber].iPrefabHandleIndex >= elements[elementNumber].tPrefabHandle.Length) elements[elementNumber].iPrefabHandleIndex = 0; ObjectHandle.gameObject.SetActive(true); ObjectHandle.up = hitInfoNormal; ObjectHandle.position = v3Position; ObjectHandle.localEulerAngles = new Vector3(0,0,0); ObjectHandle.Rotate(0,CurrentAngle,0); } else if (elementNumber >= iObstacleCount && elementNumber < (iObstacleCount+iPowerupCount))//powerups { ObjectHandle = elements[elementNumber].tPrefabHandle[elements[elementNumber].iPrefabHandleIndex]; elements[elementNumber].iPrefabHandleIndex++; if (elements[elementNumber].iPrefabHandleIndex >= elements[elementNumber].tPrefabHandle.Length) elements[elementNumber].iPrefabHandleIndex = 0; ObjectHandle.gameObject.SetActive(true); ObjectHandle.up = hitInfoNormal; ObjectHandle.position = v3Position; ObjectHandle.localEulerAngles = new Vector3(0,0,0); ObjectHandle.Rotate(0,CurrentAngle,0); ((PowerupScriptCS)ObjectHandle.GetComponent(typeof(PowerupScriptCS))).initPowerupScript(); } else if (elementNumber == (iObstacleCount+iPowerupCount))//currency { ObjectHandle = elements[elementNumber].tPrefabHandle[elements[elementNumber].iPrefabHandleIndex]; elements[elementNumber].iPrefabHandleIndex++; if (elements[elementNumber].iPrefabHandleIndex >= elements[elementNumber].tPrefabHandle.Length) elements[elementNumber].iPrefabHandleIndex = 0; ObjectHandle.gameObject.SetActive(true); ObjectHandle.up = hitInfoNormal; ObjectHandle.position = v3Position; ObjectHandle.localEulerAngles = new Vector3(0,0,0); ObjectHandle.Rotate(0,CurrentAngle,0); ((PowerupScriptCS)ObjectHandle.GetComponent(typeof(PowerupScriptCS))).initPowerupScript(); } } /* * FUNCTION: Randomise an element to generate on the path * RETURNS: Element number to generate * CALLED BY: Start() * Update() * generateElements() */ private int getRandomElement() { float highestFrequency = 0; int elementIndex = 0; int i = 0; float tempFreq = 0; // Debug.Log(elements[i].elementType); if (iLastPowerupGenerated > iForcePowerupGeneration //force powerup generation if not generated for a while && !hPowerupsMainControllerCS.isPowerupActive() //ensure that a powerup is not currently active && bPowerupPlaced == false) //do not generate powerup if one is already active { // for (i= iObstacleCount; i<(iObstacleCount+iPowerupCount); i++) //{ // tempFreq = elements[i].iFrequency * Random.value; // if (highestFrequency < tempFreq) // { // highestFrequency = tempFreq; // elementIndex = i; // } //} if (_lastPowerUp == _magnetismIndex) { elementIndex = /*iObstacleCount + */ _sledgeIndex; _lastPowerUp = _sledgeIndex; } else { elementIndex = /*iObstacleCount +*/ _magnetismIndex; _lastPowerUp = _magnetismIndex; } //elementIndex = iObstacleCount + Random.Range(0,20) > 10? _magnetismIndex:_sledgeIndex; //Debug.LogWarning("PLACE POWERUP " + elements[elementIndex].tPrefabHandle[0].name); //#if UNITY_EDITOR // UnityEditor.Selection.activeGameObject = elements[elementIndex].tPrefabHandle[0].gameObject; // UnityEditor.EditorApplication.isPaused = true; //#endif iLastPowerupGenerated = 0;//reset variable } else//normal case; generate any random element { for (i=0; i(); if (pvs.powerupType == PowerupsMainControllerCS.PowerUps.Magnetism) { _magnetismIndex = i; } if (pvs.powerupType == PowerupsMainControllerCS.PowerUps.SuperSledge) { _sledgeIndex = i; } elements[i].iFrequency = pvs.frequency; elements[i].tPrefabHandle = new Transform[elements[i].iFrequency]; elements[i].iPrefabHandleIndex = 0; elements[i].elementType = ElementType.Powerup; for (int j=0; j