void Start()
	{
		// get the transform of the main camera
		if (Camera.main != null)
		{
			cam = Camera.main.transform;
		}
		else
		{
			Debug.LogWarning("Where's your main camera?!");
		}
		_detectionRadius = transform.GetComponentInChildren<DetectionRadius> ();
	}
Beispiel #2
0
	// A manual way to change a target. I use this for having an AI
	// character randomly change their target to someone who attacked them if they
	// don't have them targeted already.
	public void ChangeTarget(Transform newTarget)
	{
		_charAttacking.TargetedCharacter = newTarget;
		// AI players also retarget the same way human players do.
		if(!_charStatus.IsEnemy)
			Manager_Targeting.instance.TargetACharacter(_charStatus.PlayerNumber, _charAttacking);
		if (newTarget) // Make sure the target is not null just in case.
		{
			targetCharStatus = newTarget.GetComponent<CharacterStatus>();
			targetDetRadius = targetCharStatus.detectionRadius;
			this.targetForNavMesh = newTarget;
		}
	}
Beispiel #3
0
	// Find our nearest target, whether it be a player, enemy, or item, based
	// on what state we are currently in and what is available.
	Transform FindNearestTarget()
	{
		Transform nearestTarget = null;
		if( (aiState != AIStates.Pursue_Item && ( (!IsEnemy && Manager_Targeting.instance.enemyTargets.Count == 0)
		     || (IsEnemy && Manager_Targeting.instance.playerTargets.Count == 0) ) )
		   || (aiState == AIStates.Pursue_Item && (detectionRadius == null
		   || detectionRadius.inRangeItems.Count == 0 && detectionRadius.itemStorersInRange.Count == 0)))
		{
			if(aiState == AIStates.Pursue_Item)
				aiState = AIStates.Pursue; // If we were pursuing an item, there were none nearby so pursue again.
			return null;
		}
		// Setup our correct target list to check from.
		float shortestSoFar = 100;
		List<Transform> targets = Manager_Targeting.instance.playerTargets;
		if(aiState == AIStates.Pursue_Item)
		{
			// Put the names of all of your healing items in that Any() and All() parts I have
			// since that checks for healing items. You can just put a part of
			// their name. They will only attempt to go after those if their
			// health isn't maxed. If any are not healing, they will go after any of the
			// ones that aren't healing then using All to make sure the item's name is not in _healingItemNames.
			// You can check below in the foreach loop where we check for dist < shortestSoFar
			if(detectionRadius.inRangeItems.Count > 0 && ( (_charStatus.Stats[0] < _charStatus.Stats[1]
				&& detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.Any(itemName => item.name.Contains(itemName)) ) )
				|| (detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.All(itemName => !item.name.Contains(itemName)) ) )) )
				targets = detectionRadius.inRangeItems;
			else if(detectionRadius.itemStorersInRange.Count > 0)
				targets = detectionRadius.itemStorersInRange;
			else
			{
				// No need to pursue item then. This stuff is here just in case we
				// reach here.
				aiState = AIStates.Wander;
				targetForNavMesh = null;
				return null;
			}
		}
		else // Not pursuing an item.
		{
			// For players to target enemies.
			if(!IsEnemy)
				targets = Manager_Targeting.instance.enemyTargets;
		}
		foreach(Transform curTarget in targets)
		{
			if(curTarget != null)
			{
				// Just another check seeing if an item checking doesn't have a parent.
				// Detection radius already does this but double checks can be good.
				// If a character is what we are looking at, we make sure they are
				// alive.
				if(((curTarget.tag == "Player" || curTarget.tag == "Enemy") && curTarget.GetComponent<CharacterStatus>().Stats[0] > 0)
				   || (curTarget.tag == "ItemStorer" || (curTarget.tag == "Item" && curTarget.parent == null)))
				{
					if(curTarget.tag == "Item"
					   && curTarget.GetComponent<Base_Item>().ItemType == Base_Item.ItemTypes.Collectable)
					{
						// If we are checking an item and we have less than
						// 90% health left and the item is a collectable, we will
						// go for that right away.
						if(_charStatus.Stats[0] < _charStatus.Stats[1] * 0.9f)
						{
							nearestTarget = curTarget;
							break;
						}
					}
					float dist = Vector3.Distance(transform.position, curTarget.position);
					// Here we check to see that the distance checking is less than the shortest so far.
					// Then we see if the curTarget is not an item, or if it is, we see that we have less than
					// max health and the curTarget is a healing item, otherwise, we simply check that it is not
					// a healing item.
					if(dist < shortestSoFar && (curTarget.tag != "Item" || ( (_charStatus.Stats[0] < _charStatus.Stats[1] && _healingItemNames.Any(itemName => curTarget.name.Contains(itemName) ) )
						|| (_healingItemNames.All(itemName => !curTarget.name.Contains(itemName) ) ) ) ) )
					{
						shortestSoFar = dist;
						nearestTarget = curTarget;
					}
				}
			}
		}
		if(nearestTarget != null)
		{
			if(nearestTarget.tag == "Player" || nearestTarget.tag == "Enemy")
			{
				// We now have a targeted character.
				_charAttacking.TargetedCharacter = nearestTarget;
				// AI players also retarget the same way human players do.
				if(gameObject.tag == "Player")
					Manager_Targeting.instance.TargetACharacter(_charStatus.PlayerNumber, _charAttacking);
				// Get references from them.
				targetCharStatus = nearestTarget.GetComponent<CharacterStatus>();
				targetDetRadius = targetCharStatus.detectionRadius;
			}
			this.targetForNavMesh = nearestTarget;
		}
		return nearestTarget;
	}