/// <summary> /// Adds new obstacle to the pool. /// </summary> /// <param name="obstacleData">Data defining the obstacle.</param> private void AddNewObstacle(ObstacleIniData obstacleData) { var newObstacle = _obstacleFactory.CreateObstacle(StoredObstaclesType, obstacleData); newObstacle.DeactivationCallback = DeactivateObstacle; _obstacles.Add(newObstacle); }
/// <summary> /// Creates obstacle basing on provided arguments. /// </summary> /// <param name="type">Type of the obstacle to create.</param> /// <param name="iniData">Initialization data for the obstacle.</param> /// <returns></returns> public IObstacle CreateObstacle(ObstacleTypeEnum type, ObstacleIniData iniData) { switch (type) { case ObstacleTypeEnum.PhysicalBlock: return(CreatePhysicalObstacle(iniData)); case ObstacleTypeEnum.EnergyBlock: return(CreateEnergyObstacle(iniData)); } throw new Exception("Error - Not recognized obstacle type."); }
/// <summary> /// Creates energy obstacle. /// </summary> /// <param name="iniData">Initialization data for the obstacle.</param> /// <returns></returns> private IObstacle CreateEnergyObstacle(ObstacleIniData iniData) { var newObstacle = Instantiate(_energyObstaclePrefab, iniData.Position, iniData.Rotation); newObstacle.transform.localScale = iniData.Scale; IObstacle newObstacleController = newObstacle.GetComponent <EnergyBlockController>(); if (newObstacleController == null) { throw new Exception("Error - Energy obstacle controller not found!"); } return(newObstacleController); }
/// <summary> /// Applies new data to obstacle. /// </summary> /// <param name="newData">Data to be applied to obstacle.</param> public void Mutate(ObstacleIniData newData) { gameObject.transform.position = newData.Position; gameObject.transform.localScale = newData.Scale; gameObject.transform.rotation = newData.Rotation; _rigidBody.mass = newData.Mass; if (_simpleMover != null) { _simpleMover.ConstantForce = newData.ConstantForce; } if (newData.ParentTransform != null) { gameObject.transform.SetParent(newData.ParentTransform); } }
/// <summary> /// Returns randomized, accordingly to provided in editor configuration, obstacle data. /// </summary> /// <returns></returns> public ObstacleIniData GetRandomizedObstacleData(ObstacleTypeEnum obstacleType) { var obstacleIniData = new ObstacleIniData(); var positionVector = new Vector3(); positionVector.x = GetRandomNumber(_maxPosition.x, _minPosition.x) * _smallestLengthUnit; positionVector.y = GetRandomNumber(_maxPosition.y, _minPosition.y) * _smallestLengthUnit; positionVector.z = GetRandomNumber(_maxPosition.z, _minPosition.z) * _smallestLengthUnit; var scaleVector = GetScaleVector(obstacleType); obstacleIniData.Position = positionVector; obstacleIniData.Scale = scaleVector; obstacleIniData.ParentTransform = _parentTransform; obstacleIniData.Mass = CalculateMass(obstacleType, scaleVector); return(obstacleIniData); }
/// <summary> /// Spawns obstacle using provided obstacle data, if possible. /// </summary> /// <param name="obstacleData">Data concerning the obstacle.</param> public void SpawnObstacle(ObstacleIniData obstacleData) { //If there are no free obstacles left - create new one. Do not use it yet - it has to be initialized first //what will happen during next frame. if (_obstacles.Count <= 0) { if (_obstaclesInUse < MaxObstacles) { AddNewObstacle(obstacleData); _obstaclesInUse++; } } //Otherwise mutate first object in the free list and use it. else { var obstacleToActivate = _obstacles[0]; obstacleToActivate.Mutate(obstacleData); ActivateObstacle(0); } }
/// <summary> /// Creates new obstacles pool. If maxObstacles is smaller than startingObstaclesAmount - the latter will /// have assigned the value of the first one. /// </summary> /// <param name="obstacleTypeEnum">Type of the obstacle that this pool will be storing.</param> /// <param name="obstacleFactory">Factory used to create the obstacles.</param> /// <param name="maxObstacles">Maximal amount of obstacles this pool can store.</param> /// <param name="startingObstaclesAmount">Starting amount of obstacles that will be instantly ready.</param> public ObstaclesPool(ObstacleTypeEnum obstacleTypeEnum, IObstacleFactory obstacleFactory, int maxObstacles, int startingObstaclesAmount) { if (maxObstacles < startingObstaclesAmount) { startingObstaclesAmount = maxObstacles; } StoredObstaclesType = obstacleTypeEnum; _obstacleFactory = obstacleFactory; MaxObstacles = maxObstacles; BeginningObstacles = startingObstaclesAmount; int beginningObstaclesCount = MaxObstacles > BeginningObstacles ? BeginningObstacles : MaxObstacles; var obstacleData = new ObstacleIniData(); for (int i = 0; i < beginningObstaclesCount; i++) { AddNewObstacle(obstacleData); _obstaclesInUse++; } }
/// <summary> /// Merges two energy blocks together. Smaller block will be deactivated later. /// Bigger block will get bigger on the smallest dimension. /// </summary> private void MergeBlocks(EnergyBlockController otherBlock) { if (otherBlock._isActive == false || this._isActive == false) { return; } var calculator = Calculations.GetInstance(); float thisCuboidVolume = calculator.CalcCuboidVolume(transform.localScale); float otherCuboidVolume = calculator.CalcCuboidVolume(otherBlock.transform.localScale); var biggerCuboid = thisCuboidVolume >= otherCuboidVolume ? this : otherBlock; var smallerCuboid = biggerCuboid == this ? otherBlock : this; Vector3 biggerCuboidDims = biggerCuboid.transform.localScale; //Find out which dimension is the biggest, which smallest and which is in between. float biggestDim = Math.Max(biggerCuboidDims.x, Math.Max(biggerCuboidDims.y, biggerCuboidDims.z)); float smallestDim = Math.Min(biggerCuboidDims.x, Math.Min(biggerCuboidDims.y, biggerCuboidDims.z)); float mediocreDim = biggerCuboidDims.z; if (biggerCuboidDims.x < biggestDim && biggerCuboidDims.x > smallestDim) { mediocreDim = biggerCuboidDims.x; } else if (biggerCuboidDims.y < biggestDim && biggerCuboidDims.y > smallestDim) { mediocreDim = biggerCuboidDims.y; } //Calculate value by which the smallest dimension of the bigger cuboid will be increased. float smallestDimAddition = calculator.DivideVolumeByArea(biggestDim, mediocreDim, Math.Min(thisCuboidVolume, otherCuboidVolume)); //Find which dimension of the scale vector is the smallest. Could use equal operator, but these are floats after all... if (biggerCuboidDims.x < biggestDim && biggerCuboidDims.x < mediocreDim) { biggerCuboidDims.x += smallestDimAddition; } else if (biggerCuboidDims.y < biggestDim && biggerCuboidDims.y < mediocreDim) { biggerCuboidDims.y += smallestDimAddition; } else { biggerCuboidDims.z += smallestDimAddition; } float newMass = _rigidBody.mass + otherBlock._rigidBody.mass; Vector3 newConstantForce = _simpleMover.ConstantForce + otherBlock._simpleMover.ConstantForce; //Prepare mutation data. var mutationData = new ObstacleIniData() { Mass = newMass, ConstantForce = newConstantForce, Scale = biggerCuboidDims, Rotation = transform.rotation, ParentTransform = transform.parent, Position = transform.position }; otherBlock.Deactivate(); Mutate(mutationData); }