protected virtual bool Attack(unitScript unit, unitScript clickedUnit) { //determine attack type if (unit.getCurrentWeapon().type == WeaponType.melee) { return(MeleeAttack(unit, clickedUnit)); } if (unit.getCurrentWeapon().type == WeaponType.ranged) { return(RangedAttack(unit, clickedUnit)); } return(false); }
protected bool RangedAttack(unitScript unit, unitScript clickedUnit, bool initialAttack = true) { // Check LoS if (!canSee(unit, clickedUnit)) { return(false); } if (hitShield(unit, clickedUnit)) { return(true); } //Resolve Attack float roll = UnityEngine.Random.Range(0.0f, 1.0f); float chanceToHit = rangedChanceToHit(unit, clickedUnit); print(roll + " " + chanceToHit); if (roll < chanceToHit) { clickedUnit.takeDamage(unit.getCurrentWeapon().damage); } else { clickedUnit.displayMiss(); } unit.activateAttack(); if (initialAttack && clickedUnit.getStrikeback() == false) { bool result; if (clickedUnit.getCurrentWeapon().type == WeaponType.melee) { result = MeleeAttack(clickedUnit, unit, false); } else if (clickedUnit.getCurrentWeapon().type == WeaponType.ranged) { result = RangedAttack(clickedUnit, unit, false); } else { result = false; } if (result) { clickedUnit.useStrikeback(); } } return(true); }
protected float meleeChanceToHit(unitScript unit, unitScript clickedUnit) { if (unit.getCurrentWeapon().type == WeaponType.ranged) { return(0); } // Check outflank bonus int flankBonus = 0; // Flank Check Vector2 enemyPosition = clickedUnit.GetComponent <GridItem>().getPos(); foreach (unitScript u in playerUnitList) { if (u != null) { Vector2 unitPosition = u.GetComponent <GridItem>().getPos(); if (u.getOwner() == controllerID && u != unit && Vector2.Distance(unitPosition, enemyPosition) < 2) { flankBonus = 2; print("Flanked Bitches"); } } } // return chance to hit return((5.0f + (unit.getSkill() + flankBonus) - clickedUnit.getSkill()) / 10.0f); }
public void loadWeaponData(unitScript u, bool ally) { var WeaponPanel = transform.FindChild(ally?"WeaponPanel":"EnemyWeaponPanel"); WeaponPanel.gameObject.SetActive(true); var weapon = u.getCurrentWeapon(); WeaponPanel.transform.Find("Weapon").GetComponent <Text>().text = weapon.name; WeaponPanel.transform.Find("Damage").GetComponent <Text>().text = weapon.damage.ToString(); var rangedPanel = WeaponPanel.transform.Find("Ranged"); switch (weapon.type) { case WeaponType.ranged: rangedPanel.gameObject.SetActive(true); RangedWeapon current = (RangedWeapon)weapon; rangedPanel.Find("ShortRange").GetComponent <Text>().text = current.minRange.ToString(); rangedPanel.Find("LongRange").GetComponent <Text>().text = current.maxRange.ToString(); break; default: rangedPanel.gameObject.SetActive(false); break; } }
protected float getRangePenalty(unitScript unit, float distance) { RangedWeapon weapon; float rangedPenalty = 0.0f; try { weapon = (RangedWeapon)unit.getCurrentWeapon(); } catch (InvalidCastException e) { return(distance > unit.getMovementDistance() + 2 ? 0 : 100); } if (weapon.minRange > distance) { rangedPenalty = weapon.minRange - distance; } else if (weapon.maxRange < distance) { rangedPenalty = distance - weapon.maxRange; } else { rangedPenalty = 0; } return(rangedPenalty); }
protected bool activateShield(unitScript unit, GridItem position) { if (!(unit.getCurrentWeapon().type == WeaponType.shield)) { return(false); } Shield currentShield = (Shield)unit.getCurrentWeapon(); if (currentShield.isBroken(unit.GetInstanceID())) { return(false); } if (currentShield.getShield(unit.GetInstanceID()) != null) { Destroy(currentShield.getShield(unit.GetInstanceID())); } //Check position is within range if (currentShield == null || Vector2.Distance(unit.GetComponent <GridItem>().getPos(), position.getPos()) > currentShield.range) { return(false); } //Create the game object //TODO- Fix the roation and shape of shields to be frontal not surround Vector3 toPosition = position.getVectorPostion() - unit.GetComponent <GridItem>().getVectorPostion(); float rotation = Vector3.Angle(new Vector3(0, 0, 1), Vector3.Cross(toPosition, new Vector3(0, 1, 0))); print(rotation); GameObject newShield = Instantiate <GameObject>(Resources.Load <GameObject>("Units/Shield"), position.getVectorPostion(), Quaternion.Euler(0, rotation, 0)); currentShield.setShield(unit.GetInstanceID(), newShield); newShield.GetComponent <shieldScript>().setStats(controllerID, unit.getSmarts() * 3); //Check it's collisions with other shields currentShield.shieldBreakCheck(); unit.activateAttack(); print("ACTIVATE SHIELD"); map.UnHilightMap(); return(true); }
protected bool MeleeAttack(unitScript unit, unitScript clickedUnit, bool initialAttack = true) { // Check attack can occur if (unit.getCurrentWeapon().type == WeaponType.ranged || unit == null || clickedUnit == null) { return(false); } float distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), clickedUnit.GetComponent <GridItem>().getPos()); if (!(unit.getCurrentWeapon().type == WeaponType.melee) || distance > ((MeleeWeapon)unit.getCurrentWeapon()).range) { return(false); } // Given it can roll the dice float roll = UnityEngine.Random.Range(0.0f, 1.0f); float chanceToHit = meleeChanceToHit(unit, clickedUnit); print(roll + " " + chanceToHit); if (roll < chanceToHit) { clickedUnit.takeDamage(unit.getStrength() + unit.getCurrentWeapon().damage); } else { clickedUnit.displayMiss(); } unit.activateAttack(); if (initialAttack && clickedUnit.getStrikeback() == false) { bool result = MeleeAttack(clickedUnit, unit, false); if (result) { clickedUnit.useStrikeback(); } } return(true); }
public void loadCombatData(unitScript attacker, unitScript defender, float AttackerChanceToHit, float defenderChanceToHit) { Transform combatPanel = transform.Find("CombatPanel"); Transform EnemyPanel = combatPanel.Find("EnemyPanel"); var targetText = EnemyPanel.Find("Target").GetComponent <UnityEngine.UI.Text>(); targetText.text = defender.getName(); var classText = EnemyPanel.Find("Class").GetComponent <UnityEngine.UI.Text>(); classText.text = defender.getClass(); var healthText = EnemyPanel.Find("Health").GetComponent <UnityEngine.UI.Text>(); healthText.text = defender.getHealth().ToString() + " : " + defender.getMaxHealth().ToString(); var strikeBack = EnemyPanel.Find("StrikeBack").GetComponent <Text>(); strikeBack.text = (!defender.getStrikeback()).ToString(); var strikebackChanceText = EnemyPanel.Find("ChanceText").GetComponent <Text>(); var strikebackDamageText = EnemyPanel.Find("DamageText").GetComponent <Text>(); var strikebackChance = EnemyPanel.Find("Chance").GetComponent <Text>(); var strikebackDamage = EnemyPanel.Find("Damage").GetComponent <Text>(); if (!defender.getStrikeback()) { strikebackChance.enabled = true; strikebackDamage.enabled = true; strikebackChanceText.enabled = true; strikebackDamageText.enabled = true; strikebackChance.text = defenderChanceToHit.ToString(); strikebackDamage.text = defender.getCurrentWeapon().damage.ToString(); } else { strikebackChance.enabled = false; strikebackDamage.enabled = false; strikebackChanceText.enabled = false; strikebackDamageText.enabled = false; } int chance = (int)Mathf.Max(0, Mathf.Min(100, AttackerChanceToHit * 100)); combatPanel.Find("ChanceToHit").GetComponent <UnityEngine.UI.Text>().text = (chance).ToString() + "%"; combatPanel.Find("Damage").GetComponent <UnityEngine.UI.Text>().text = unit.getCurrentWeapon().damage.ToString(); }
// Update is called once per frame void Update() { if (unit != null) { if (unit.canOpenDoor()) { transform.FindChild("CharacterPanel").FindChild("DoorButton").GetComponent <Button>().interactable = true; } else { transform.FindChild("CharacterPanel").FindChild("DoorButton").GetComponent <Button>().interactable = false; } if (unit.getCurrentWeapon().type != lastWeaponType) { Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton"); attackButton.FindChild("CrossHair").gameObject.SetActive(false); attackButton.FindChild("Sword").gameObject.SetActive(false); attackButton.FindChild("Shield").gameObject.SetActive(false); if (unit.getCurrentWeapon().type == WeaponType.ranged) { attackButton.FindChild("CrossHair").gameObject.SetActive(true); } else if (unit.getCurrentWeapon().type == WeaponType.melee) { attackButton.FindChild("Sword").gameObject.SetActive(true); } else if (unit.getCurrentWeapon().type == WeaponType.shield) { attackButton.FindChild("Shield").gameObject.SetActive(true); } lastWeaponType = unit.getCurrentWeapon().type; } if (unit.hasAttacked() || unit.isMoving() || (unit.getCurrentWeapon().type == WeaponType.shield && ((Shield)unit.getCurrentWeapon()).isBroken(unit.GetInstanceID()))) { Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton"); attackButton.GetComponent <Button>().interactable = false; } else { Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton"); attackButton.GetComponent <Button>().interactable = true; } } }
protected float rangedChanceToHit(unitScript unit, unitScript clickedUnit) { if (unit.getCurrentWeapon().type == WeaponType.melee) { return(0.0f); } //Calculate range penalty float distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), clickedUnit.GetComponent <GridItem>().getPos()); float rangedPenalty = getRangePenalty(unit, distance); //Calculate cover penalty float coverPenalty = getCoverPenalty(unit, clickedUnit, distance); //Get base shooting skill float shootingSkill = getBaseHitChance(unit); //Return formula return(shootingSkill - (rangedPenalty + coverPenalty) / 10); }
protected bool hitShield(unitScript unit, unitScript clickedUnit) { Ray ray = new Ray(unit.transform.position + new Vector3(0, 1, 0), (clickedUnit.transform.position + new Vector3(0, 1, 0) - unit.transform.position + new Vector3(0, 1, 0))); float distance = Vector3.Distance(unit.transform.position, clickedUnit.transform.position); RaycastHit[] hits = Physics.RaycastAll(ray, distance).OrderBy(h => h.distance).ToArray(); foreach (RaycastHit hit in hits) { if (hit.transform.gameObject.layer == 11) { shieldScript shield = hit.transform.gameObject.GetComponent <shieldScript>(); if (shield.owner != controllerID) { shield.takeDamage(unit.getCurrentWeapon().damage); } return(true); } } return(false); }
void unitSelectedRightClick(RaycastHit hit, unitScript unit) { clickableTile tile = hit.collider.gameObject.GetComponent <clickableTile>(); if (tile) { GridItem tilePos = tile.GetComponent <GridItem>(); GridItem pos = selected.GetComponent <GridItem>(); if (!unit.hasMoved()) { //draw path only if not in attack mode Vector2[] path = pathFinder.drawPath(tilePos.getPos(), !attackMode); if (path != null) { if (!attackMode && !unit.hasMoved()) { map.UnHilightMap(); //map.toggleHighlight(false, Color.white, pos.getX(), pos.getY(), unit.getSpeed()); unit.setPath(path); pathFinder.setPathfinding(false); } } } if (attackMode && unit.getCurrentWeapon().type == WeaponType.shield) { activateShield(unit, tilePos); } } //If not tile may be unit unitScript clickedUnit = hit.collider.gameObject.GetComponent <unitScript>(); // if is enemy unit if (attackMode && !unit.hasAttacked() && clickedUnit && clickedUnit.getOwner() != 0) { Attack(unit, clickedUnit); } }
//Assisting functions unitScript targetPrioritisation(unitScript unit, List <unitScript> enemyList) { AIUnitController unitControl = unit.GetComponent <AIUnitController>(); List <float> priorites = new List <float>(); foreach (unitScript otherUnit in enemyList) { //Add factors float priority = 0; if (otherUnit == null || otherUnit.getOwner() == controllerID || otherUnit.getHealth() <= 0) { priorites.Add(-1000000); break; } //distance - wrecklessness (negative if over wrecklessness priority -= Mathf.Max(0, Vector2.Distance(unit.GetComponent <GridItem>().getPos(), otherUnit.GetComponent <GridItem>().getPos()) - unitControl.wrecklessness); //deuling preference bool weaponsMatch = unit.getCurrentWeapon().type == otherUnit.getCurrentWeapon().type; if ((weaponsMatch && unitControl.deulingPreference) || (!weaponsMatch && !unitControl.deulingPreference)) { priority += 2; } //Agro multiplied by anger if (unitControl.agroTarget == otherUnit) { priority += 10 * unitControl.anger; } priorites.Add(priority); } priorites.ForEach(e => print("Inlist" + e)); int maxIndex = priorites.IndexOf(priorites.Max()); unitControl.target = enemyList[maxIndex]; print("Selected : " + enemyList[maxIndex]); return(enemyList[maxIndex]); }
void AttackCommand() { if (attackMode) { attackMode = false; rangeRenderer.enabled = false; map.UnHilightMap(); selectUnit(selected.GetComponent <unitScript>()); } else { unitScript unit = selected.GetComponent <unitScript>(); if (unit.hasAttacked()) { return; } Weapon currentWeapon = unit.getCurrentWeapon(); GridItem pos = selected.GetComponent <GridItem>(); map.UnHilightMap(); if (currentWeapon.type == WeaponType.melee) { MeleeWeapon currentMeleeWeapon = (MeleeWeapon)currentWeapon; map.toggleHighlight(true, Color.red, pos.getX(), pos.getY(), currentMeleeWeapon.range); } else if (currentWeapon.type == WeaponType.shield) { Shield currentShield = (Shield)currentWeapon; map.toggleHighlight(true, Color.yellow, pos.getX(), pos.getY(), currentShield.range); } attackMode = true; pathFinder.setPathfinding(false); } }
void mouseOver() { //Mouse over tile while unit selected if (selected) { unitScript unit = selected.GetComponent <unitScript>(); if (unit != null && unit.getOwner() == 0) { RaycastHit hit; var ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, Mathf.Infinity, (1 << 8))) { clickableTile tile = hit.collider.gameObject.GetComponent <clickableTile>(); if (tile && !unit.hasMoved() && !attackMode) { GridItem tilePos = tile.GetComponent <GridItem>(); //print(tilePos); if (pathFinder != null) { pathFinder.drawPath(tilePos.getPos()); } else { print("pathfinder dead"); } } unitScript enemyUnit = hit.collider.GetComponent <unitScript>(); if (enemyUnit && attackMode == true && enemyUnit.getOwner() != 0) { GridItem playerPos = unit.GetComponent <GridItem>(); GridItem enemyPos = hit.collider.GetComponent <GridItem>(); MeleeWeapon currentMeleeWeapon = null; if (unit.getCurrentWeapon().type == WeaponType.melee) { currentMeleeWeapon = (MeleeWeapon)unit.getCurrentWeapon(); bool withinMeleeRange = currentMeleeWeapon != null && Vector2.Distance(enemyPos.getPos(), playerPos.getPos()) <= currentMeleeWeapon.range; if (withinMeleeRange || currentMeleeWeapon == null) { GUIController cont = gui.GetComponent <GUIController>(); cont.setCombatPanelVisibility(true, unit, enemyUnit, meleeChanceToHit(unit, enemyUnit)); } } else if (unit.getCurrentWeapon().type == WeaponType.ranged) { if (canSee(unit, enemyUnit)) { rangeRenderer.enabled = true; updateRangefinder(unit, enemyUnit.GetComponent <GridItem>()); GUIController cont = gui.GetComponent <GUIController>(); float distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), enemyUnit.GetComponent <GridItem>().getPos()); cont.setCombatPanelVisibility(true, unit, enemyUnit, rangedChanceToHit(unit, enemyUnit)); cont.loadRangedData(isShielded(unit, enemyUnit), getBaseHitChance(unit), getRangePenalty(unit, distance), getCoverPenalty(unit, enemyUnit, distance)); } else if (rangeRenderer.enabled == true) { rangeRenderer.enabled = false; } } } else { GUIController cont = gui.GetComponent <GUIController>(); cont.setCombatPanelVisibility(false); rangeRenderer.enabled = false; } } } } //We also want to set the enemyStatPanel RaycastHit result; Ray line = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(line, out result, Mathf.Infinity, (1 << 8))) { //set selected to hit GameObject enemy = result.collider.gameObject; //Select new unit if (enemy) { var guiCont = gui.GetComponent <GUIController>(); unitScript unit = enemy.GetComponent <unitScript>(); if (unit != null && unit.getOwner() == 1) { guiCont.setCharacterPanelVisibility(true, unit, false); } else { guiCont.setCharacterPanelVisibility(false, null, false); } } } }
void hunt(unitScript unit) { pathFinder.getMovementPaths(unit.GetComponent <GridItem>().getPos(), 100, false); //var locations = pathFinder.getReachableLocations(); if (unit.getCurrentWeapon().type == WeaponType.melee) { if (!unit.GetComponent <AIUnitController>().moved) { //get position of all enemies unitScript[] units = getAllUnits(); List <unitScript> targetList = new List <unitScript>(units); //Pick target unitScript target = targetPrioritisation(unit, targetList); if (target == null) { unit.GetComponent <AIUnitController>().moved = true; unit.GetComponent <AIUnitController>().attacked = true; return; } unit.GetComponent <AIUnitController>().moved = true; //Get the positions one short of target var oneShort = target.GetComponent <GridItem>().getPos() - unit.GetComponent <GridItem>().getPos(); var targetPosXclose = target.GetComponent <GridItem>().getPos() - new Vector2(Mathf.Sign(oneShort.x), 0); var targetPosYclose = target.GetComponent <GridItem>().getPos() - new Vector2(0, Mathf.Sign(oneShort.y)); var targetPosXfar = target.GetComponent <GridItem>().getPos() + new Vector2(Mathf.Sign(oneShort.x), 0); var targetPosYfar = target.GetComponent <GridItem>().getPos() + new Vector2(0, Mathf.Sign(oneShort.y)); List <Vector2[]> paths = new List <Vector2[]>(); paths.Add(pathFinder.drawPath(targetPosXclose, false, true)); paths.Add(pathFinder.drawPath(targetPosYclose, false, true)); paths.Add(pathFinder.drawPath(targetPosXfar, false, true)); paths.Add(pathFinder.drawPath(targetPosYfar, false, true)); //For each potential places try to move there foreach (var path in paths) { if (path != null) { //if the path is not null attack Vector2[] newPath = new Vector2[Mathf.Min(path.Length, unit.getMovementDistance())]; for (int i = 0; i < newPath.Length; i++) { newPath[i] = path[i]; } unit.setPath(newPath); break; } } unit.GetComponent <AIUnitController>().moved = true; } else if (unit.canEndTurn()) { //Attack target MeleeAttack(unit, unit.GetComponent <AIUnitController>().target); unit.GetComponent <AIUnitController>().attacked = true; } } else if (unit.getCurrentWeapon().type == WeaponType.ranged) { if (!unit.GetComponent <AIUnitController>().moved) { Vector2 initialPosition = unit.GetComponent <GridItem>().getPos(); //Initialise heursticmap var locations = pathFinder.getReachableLocations(); Dictionary <Vector2, float> heuristicMap = new Dictionary <Vector2, float>(); RangedWeapon currentGun = (RangedWeapon)unit.getCurrentWeapon(); var enemyUnits = getEnemyUnits(); foreach (Vector2 pos in locations.Where(p => Mathf.Abs(p.x - unit.GetComponent <GridItem>().getPos().x) + Mathf.Abs(p.y - unit.GetComponent <GridItem>().getPos().y) < unit.getMovementDistance())) { unit.setPosition((int)pos.x, (int)pos.y); float h = 0.0f; //Get all cover tiles around the current var neighboringTiles = this.map.getAllNeighbours(pos).Where(p => this.map.getTileData(p).coverValue != 0); //How much will this tile hurt? h += enemyUnits.Where(e => getRangePenalty(e, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0) .Aggregate(0, (subHeuristic, enemy) => subHeuristic - 1); //Add back all values from cover foreach (Vector2 cover in neighboringTiles) { //Direction of cover Vector2 vectorToCover = cover - pos; //If the cover is between me and an enemy then increase heurstic h += enemyUnits .Where( e => // The enemy is not melee or shield e.getCurrentWeapon().type == WeaponType.ranged && //I am within enemy range getRangePenalty(e, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0 && //And cover is between the enemy and myself (Vector2.Angle(e.GetComponent <GridItem>().getPos() - pos, vectorToCover) < 45) ).Aggregate(0, (subHeurstic, e) => subHeurstic + (this.map.getTileData(cover).coverValue + 2)); } // How much damage can I do from this position h += enemyUnits.Select(e => getRangePenalty(unit, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0) .Aggregate(0, (subHeurisitic, e) => subHeurisitic + (e?1:-1));//unit.getCurrentWeapon().damage); heuristicMap[pos] = h; this.map.displayDebugData((int)pos.x, (int)pos.y, h.ToString()); unit.setPosition((int)initialPosition.x, (int)initialPosition.y); } unit.setPosition((int)initialPosition.x, (int)initialPosition.y); //Pick location with highest score Vector2 moveLocation = heuristicMap.Aggregate((l, r) => l.Value >= r.Value ? l : r).Key; print("KEY/Value " + moveLocation + " " + heuristicMap[moveLocation]); //Move there var path = pathFinder.drawPath(moveLocation, false, true); //if the path is not null attack Vector2[] newPath = new Vector2[Mathf.Min(path.Length, unit.getMovementDistance())]; for (int i = 0; i < newPath.Length; i++) { newPath[i] = path[i]; } unit.setPath(newPath); unit.GetComponent <AIUnitController>().moved = true; //If an attack can be made make it } if (unit.canEndTurn()) { //Find best target unitScript target = targetPrioritisation(unit, getEnemyUnits()); if (target == null) { unit.GetComponent <AIUnitController>().attacked = true; return; } //Attack target RangedAttack(unit, unit.GetComponent <AIUnitController>().target); unit.GetComponent <AIUnitController>().attacked = true; } } else if (unit.getCurrentWeapon().type == WeaponType.shield) { if (swapTo(unit, WeaponType.melee)) { print("ready Sword"); } else if (swapTo(unit, WeaponType.ranged)) { print("ready Gun"); } } }
void updateRangefinder(unitScript unit, GridItem position) { RangedWeapon weapon = (RangedWeapon)unit.getCurrentWeapon(); // Set line data Vector3[] positions = new Vector3[4]; positions[0] = new Vector3(unit.GetComponent <GridItem>().getX(), 1.0f, unit.GetComponent <GridItem>().getY()); positions[3] = new Vector3(position.getX(), 1.0f, position.getY()); float distance = Vector3.Distance(positions[0], positions[3]); positions[1] = Vector3.Lerp(positions[0], positions[3], Mathf.Max(0.001f, weapon.minRange / distance)); positions[2] = Vector3.Lerp(positions[0], positions[3], Mathf.Min(0.9999f, (float)weapon.maxRange / distance)); rangeRenderer.numPositions = 4; rangeRenderer.SetPositions(positions); GradientColorKey[] colorKey = new GradientColorKey[4]; GradientAlphaKey[] alphaKey = new GradientAlphaKey[2]; //Set ends to red and red colorKey[2] = new GradientColorKey(new Color(1, 0, 0), 0.0f); Color endColor; if (distance < weapon.minRange || distance > weapon.maxRange) { endColor = new Color(1, 0, 0); } else { endColor = new Color(0, 0, 0); } colorKey[3] = new GradientColorKey(endColor, 1.0f); //Set alphaKeys alphaKey[0] = new GradientAlphaKey(1.0f, 0.0f); alphaKey[1] = new GradientAlphaKey(1.0f, 1.0f); //Set color key's two and three according to range GradientColorKey minKey, maxKey; if (distance > weapon.minRange) { minKey = new GradientColorKey(new Color(0, 0, 0), (float)weapon.minRange / distance); } else { minKey = new GradientColorKey(new Color(1, 0, 0), 0.2f); } colorKey[0] = minKey; if (distance > weapon.minRange) { maxKey = new GradientColorKey(new Color(0, 0, 0), Mathf.Min(0.99999f, (float)weapon.maxRange / distance)); } else { maxKey = new GradientColorKey(new Color(1, 0, 0), 0.5f); } colorKey[1] = maxKey; Gradient grad = new Gradient(); grad.mode = GradientMode.Blend; grad.SetKeys(colorKey, alphaKey); rangeRenderer.colorGradient = grad; }