/// <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> /// 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> /// Returns the scale vector for provided obstacle type. /// </summary> /// <param name="obstacleType">Type of the obstacle.</param> /// <returns></returns> private Vector3 GetScaleVector(ObstacleTypeEnum obstacleType) { var scaleVector = Vector3.one; switch (obstacleType) { case ObstacleTypeEnum.PhysicalBlock: scaleVector.x = GetRandomNumber(_maxPhysicalCubeScale.x, _minPhysicalCubeScale.x) * _smallestLengthUnit; scaleVector.y = GetRandomNumber(_maxPhysicalCubeScale.y, _minPhysicalCubeScale.y) * _smallestLengthUnit; scaleVector.z = GetRandomNumber(_maxPhysicalCubeScale.z, _minPhysicalCubeScale.z) * _smallestLengthUnit; break; case ObstacleTypeEnum.EnergyBlock: scaleVector.x = GetRandomNumber(_maxEnergyCubeScale.x, _minEnergyCubeScale.x) * _smallestLengthUnit; scaleVector.y = GetRandomNumber(_maxEnergyCubeScale.y, _minEnergyCubeScale.y) * _smallestLengthUnit; scaleVector.z = GetRandomNumber(_maxEnergyCubeScale.z, _minEnergyCubeScale.z) * _smallestLengthUnit; break; } return(scaleVector); }
/// <summary> /// Sets the probabilities of spawns for ALL obstacle types at once. Needs value for all types. /// </summary> /// <param name="spawnProbabilities">Key: Type of obstacle, Value: probability of spawning [0:1]. Sum should be lower or equal to 1.</param> public void SetObstacleSpawnProbabilities(Dictionary <ObstacleTypeEnum, float> spawnProbabilities) { ObstacleTypeEnum lastModifiedObstacle = ObstacleTypeEnum.EnergyBlock; float overallProbability = 0.0f; float lowerBorderProbability = 0.0f; float upperBorderProbability = 0.0f; foreach (var obstacleType in obstacleTypes) { float newProbability; if (spawnProbabilities.TryGetValue(obstacleType, out newProbability) == false) { throw new Exception($"Probabilities concerning ALL types of obstacles must be provided! {obstacleType} was not found!"); } upperBorderProbability = lowerBorderProbability + newProbability; _obstacleTypeSpawnChance.Remove(obstacleType); _obstacleTypeSpawnChance.Add(obstacleType, Tuple.Create(lowerBorderProbability, upperBorderProbability)); lowerBorderProbability = upperBorderProbability; overallProbability += newProbability; lastModifiedObstacle = obstacleType; } if (overallProbability > 1.0f) { throw new Exception( "Sum of provided probabilities in obstacle spawn probability cannot be more than 1!"); } //If the probability is lower than 1.0f - add the remaining amount to the last range. if (overallProbability < 1.0f) { Tuple <float, float> probabilityRange; _obstacleTypeSpawnChance.TryGetValue(lastModifiedObstacle, out probabilityRange); _obstacleTypeSpawnChance.Remove(lastModifiedObstacle); var newRange = Tuple.Create(probabilityRange.Item1, probabilityRange.Item2 + (1.0f - probabilityRange.Item2)); _obstacleTypeSpawnChance.Add(lastModifiedObstacle, newRange); } }
/// <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> /// Calculates mass for freshly randomized obstacle. /// </summary> /// <param name="obstacleType">Type of the obstacle which the mass is calculated for.</param> /// <param name="scale">Scale of the obstacle - defines its size, and refers to a 1x1x1 units cube.</param> /// <returns></returns> private float CalculateMass(ObstacleTypeEnum obstacleType, Vector3 scale) { float mass = 1.0f; switch (obstacleType) { case ObstacleTypeEnum.PhysicalBlock: mass = scale.x * scale.y * scale.z * _physicalCubeDensity; break; case ObstacleTypeEnum.EnergyBlock: mass = scale.x * scale.y * scale.z * _energyCubeDensity; break; } if (mass < 0.0f) { //In case someone makes a mistake and sets negative scale somewhere... And by "someone" I mean myself. mass = -mass; } return(mass); }