private bool CheckDamage(Collider target, AttackPoint point) { DamageAble victim = target.GetComponent <DamageAble>(); if (victim == null) { return(false); } if (victim.gameObject == wielder) { return(true); } DamageAble.DamageData data = new DamageAble.DamageData { damageAmount = damage, damager = this, damageOwner = wielder, direction = direction, damageSource = wielder.transform.position }; victim.ApplyDamage(data); if (hit_effect != null) { hit_effect.transform.position = point.attackRoot.position; hit_effect.time = 0; hit_effect.Play(); } return(true); }
private void FixedUpdate() { if (isInAttack) { for (int i = 0; i < attackPointArray.Length; i++) { AttackPoint ap = attackPointArray[i]; Vector3 worldPos = GetAttackPointWorldPos(ap); Vector3 attackVec = worldPos - previousAttackPos[i]; if (attackVec.magnitude < 0.001f) { attackVec = Vector3.forward * 0.0001f; } Ray r = new Ray(worldPos, attackVec.normalized); int contacts = Physics.SphereCastNonAlloc(r, ap.radius, raycastHitCache, attackVec.magnitude, targetLayers, QueryTriggerInteraction.Ignore); for (int j = 0; j < contacts; j++) { Collider col = raycastHitCache[j].collider; if (col != null) { CheckDamage(col, attackVec, worldPos); } } //update new postion previousAttackPos[i] = worldPos; } } }
private Vector3 GetAttackPointWorldPos(AttackPoint ap) { if (ap.attackRoot == null) { return(Vector3.zero); } return(ap.attackRoot.position + ap.attackRoot.transform.TransformVector(ap.offset)); }
private bool CheckDamage(Collider other, AttackPoint pts) { Damageable damageable = other.GetComponent <Damageable>(); if (damageable == null) { return(false); } if (damageable.gameObject == m_Owner) { return(true); //ignore self harm, but do not end the attack (we don't "bounce" off ourselves) } if ((targetLayers.value & (1 << other.gameObject.layer)) == 0) { //hit an object that is not in our layer, this end the attack. we "bounce" off it return(false); } if (hitAudio != null) { var renderer = other.GetComponent <Renderer>(); if (!renderer) { renderer = other.GetComponentInChildren <Renderer> (); } if (renderer) { hitAudio.PlayRandomClip(renderer.sharedMaterial); } else { hitAudio.PlayRandomClip(); } } Damageable.DamageMessage data = new Damageable.DamageMessage { amount = damage, damager = this, direction = m_Direction.normalized, damageSource = m_Owner.transform.position, throwing = m_IsThrowingHit, stopCamera = false }; damageable.ApplyDamage(data); if (hitParticlePrefab != null) { m_ParticlesPool[m_CurrentParticle].transform.position = pts.attackRoot.transform.position; m_ParticlesPool[m_CurrentParticle].time = 0; m_ParticlesPool[m_CurrentParticle].Play(); m_CurrentParticle = (m_CurrentParticle + 1) % PARTICLE_COUNT; } return(true); }
private new void Start() { base.Start(); //Debug.Log("Enemy.Start"); // reset nextTile, latched and attackPoint, for cloned (replicated) units latched = false; attackPoint = null; Transform rotatingPart = transform.Find(Constants.RotatingPart); if (rotatingPart == null) { Debug.Log("RotatingPart is NULL!"); } else { Transform head = rotatingPart.Find("Head"); if (head == null) { Debug.Log("Head is NULL!"); } else { anim = head.GetComponent <Animator>(); if (anim == null) { Debug.Log("Animator is NULL!"); } } } moveable = GetComponent <Moveable>(); if (moveable == null) { moveable = gameObject.AddComponent <Moveable>(); } //rotatingPart = transform.Find(Constants.RotatingPart); if (!Shop.instance.IsCoughing()) { moveable.SetSpeed(regularSpeed); } // todo: if coughing when this enemy is spawned, slow it down too //else // speed = replicationCoundtown = random.Next(minReplicationTime, maxReplicationTime); meleeAttackers = new List <Transform>(); towerAttackers = new List <Transform>(); }
private void crash(Collider collider, AttackPoint attackPoint) { //if (damagedObjectsList.Contains(collider.gameObject)) return; //damagedObjectsList.Add(collider.gameObject); if (audioSource) { audioSource.Play(); } StartCoroutine(owner.GetComponent <Damageable>(). locateCrashParticle(attackPoint.attackRoot.position, owner.transform.position)); }
private void OnDrawGizmosSelected() { for (int i = 0; i < attackPointArray.Length; i++) { AttackPoint ap = attackPointArray[i]; if (ap.attackRoot != null) { Vector3 worldPos = ap.attackRoot.TransformVector(ap.offset); Color green = Color.green; green.a = 0.7f; Gizmos.color = green; Gizmos.DrawWireSphere(worldPos + ap.attackRoot.position, ap.radius); } } }
private void FixedUpdate() { if (m_InAttack) { for (int i = 0; i < attackPoints.Length; ++i) { AttackPoint pts = attackPoints[i]; Vector3 worldPos = pts.attackRoot.position + pts.attackRoot.TransformVector(pts.offset); Vector3 attackVector = worldPos - m_PreviousPos[i]; if (attackVector.magnitude < 0.001f) { // A zero vector for the sphere cast don't yield any result, even if a collider overlap the "sphere" created by radius. // so we set a very tiny microscopic forward cast to be sure it will catch anything overlaping that "stationary" sphere cast attackVector = Vector3.forward * 0.0001f; } Ray r = new Ray(worldPos, attackVector.normalized); int contacts = Physics.SphereCastNonAlloc(r, pts.radius, s_RaycastHitCache, attackVector.magnitude, targetLayers.value,//~0, QueryTriggerInteraction.Ignore); for (int k = 0; k < contacts; ++k) { #if UNITY_EDITOR // helper to visualise the ground check ray in the scene view Debug.DrawLine(r.origin, r.origin + r.direction, Color.cyan); #endif Collider col = s_RaycastHitCache[k].collider; if (col != null) { CheckDamage(col, pts); } } m_PreviousPos[i] = worldPos; #if UNITY_EDITOR pts.previousPositions.Add(m_PreviousPos[i]); #endif } } }
private void OnDrawGizmosSelected() { for (int i = 0; i < attackPoints.Length; ++i) { AttackPoint pts = attackPoints[i]; if (pts.attackRoot != null) { Vector3 worldPos = pts.attackRoot.TransformVector(pts.offset); Gizmos.color = new Color(1.0f, 1.0f, 1.0f, 0.4f); Gizmos.DrawSphere(pts.attackRoot.position + worldPos, pts.radius); } if (pts.previousPositions.Count > 1) { UnityEditor.Handles.DrawAAPolyLine(10, pts.previousPositions.ToArray()); } } }
private void checkDamage(Collider collider, AttackPoint attackPoint) { Damageable damageableScript = collider.GetComponent <Damageable>(); GameObject gameObject = collider.gameObject; if (damageableScript != null && !damagedObjectsList.Contains(gameObject)) { if (collider.gameObject != owner && collider.gameObject.tag != owner.tag) { damageMessage.damageSource = attackPoint.attackRoot.transform.position; damagedObjectsList.Add(gameObject); damageableScript.applyDamage(damageMessage); burnTarget(); } } }
private bool CheckDamage(Collider other, AttackPoint pts) { Damageable d = other.GetComponent <Damageable>(); if (d == null) { return(false); } if (d.gameObject == m_Owner) { return(true); } if ((targetLayers.value & (1 << other.gameObject.layer)) == 0) { return(false); } Damageable.DamageMessage data; data.amount = damage; data.damager = this; data.direction = m_Direction.normalized; data.damageSource = m_Owner.transform.position; data.throwing = m_IsThrowingHit; data.stopCamera = false; d.ApplyDamage(data); if (hitParticlePrefab != null) { m_ParticlesPool[m_CurrentParticle].transform.position = pts.attackRoot.transform.position; m_ParticlesPool[m_CurrentParticle].time = 0; m_ParticlesPool[m_CurrentParticle].Play(); m_CurrentParticle = (m_CurrentParticle + 1) % PARTICLE_COUNT; } return(true); }
private void checkDamage(Collider collider, AttackPoint attackPoint) { Damageable damageableScript = collider.GetComponent <Damageable>(); GameObject gameObject = collider.gameObject; if (damageableScript != null && !damagedObjectsList.Contains(gameObject)) { if (damageableScript.Invincibility || collider.gameObject == owner || collider.gameObject.tag == owner.tag) { return; } damageMessage.damageSource = attackPoint.attackRoot.position; damageMessage.radius = attackPoint.radius; damagedObjectsList.Add(gameObject); damageableScript.applyDamage(damageMessage); } }
protected GameObject LookForLatchedEnemies() { GameObject chosenEnemy = null; float shortestDistance = Mathf.Infinity; GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag); foreach (GameObject ap in attackPoints) { AttackPoint attackPoint = ap.GetComponent <AttackPoint>(); if (attackPoint != null && !attackPoint.IsVacant()) { float distanceToAP = Vector2.Distance(transform.position, ap.transform.position); if (distanceToAP <= range && distanceToAP < shortestDistance) { shortestDistance = distanceToAP; chosenEnemy = attackPoint.GetOccupant().gameObject; } } } return(chosenEnemy); }
private void FixedUpdate() { if (inAttack) { for (int i = 0; i < attackPoints.Length; ++i) { AttackPoint point = attackPoints[i]; Vector3 worldPos = point.attackRoot.position + point.attackRoot.TransformVector(point.offset); Vector3 attackVector = worldPos - previousPoints[i]; if (attackVector.magnitude < 0.001f) { attackVector = Vector3.forward * 0.0001f; } Ray ray = new Ray(worldPos, attackVector.normalized); int contacts = Physics.SphereCastNonAlloc(ray, point.radius, RaycastCache, attackVector.magnitude, ~0, QueryTriggerInteraction.Ignore); for (int k = 0; k < contacts; ++k) { Collider col = RaycastCache[k].collider; if (col != null) { CheckDamage(col, point); } } previousPoints[i] = worldPos; #if UNITY_EDITOR point.previousPoints.Add(previousPoints[i]); #endif } } }
private void FixedUpdate() { if (m_InAttack) { for (int i = 0; i < attackPoints.Length; ++i) { AttackPoint pts = attackPoints[i]; Vector3 worldPos = pts.attackRoot.position + pts.attackRoot.TransformVector(pts.offset); Vector3 attackVector = worldPos - m_PreviousPos[i]; if (attackVector.magnitude < 0.001f) { attackVector = Vector3.forward * 0.0001f; } Ray r = new Ray(worldPos, attackVector.normalized); int contacts = Physics.SphereCastNonAlloc(r, pts.radius, s_RaycastHitCache, attackVector.magnitude, ~0, QueryTriggerInteraction.Ignore); for (int k = 0; k < contacts; ++k) { Collider col = s_RaycastHitCache[k].collider; if (col != null) { CheckDamage(col, pts); } } m_PreviousPos[i] = worldPos; } } }
/// <summary> Called with Invoke(). </summary> private void UpdateTarget() { // if it already has a target, see if it's dead or too far away, or if there's another one without an attacker if (target != null) { Enemy targetEnemy = target.GetComponent <Enemy>(); float distanceToTarget = Vector2.Distance(transform.position, target.transform.position); if (distanceToTarget > spotRange) { //Debug.Log("LOST TARGET"); DismissTarget(); return; } // todo: if this target has another attacker, look for nearby enemies without an attacker if (targetEnemy != null && targetEnemy.HasAnotherMeleeAttacker(transform)) { // this target has another attacker; look for other targets without an attacker GameObject[] enemies2 = GameObject.FindGameObjectsWithTag(Constants.EnemyTag); float shortestDistance2 = Mathf.Infinity; GameObject nearestEnemy2 = null; foreach (GameObject enemy in enemies2) { // if the enemy is beyond this unit's spot range, ignore target float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceToEnemy <= spotRange) { // if the enemy has another attacker, ignore it Enemy enemyEnemy = enemy.GetComponent <Enemy>(); if (enemyEnemy != null) { if (!enemyEnemy.HasAnotherMeleeAttacker(transform)) { float distanceFromUnitToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceFromUnitToEnemy < shortestDistance2) { shortestDistance2 = distanceFromUnitToEnemy; nearestEnemy2 = enemy; } } } } } if (nearestEnemy2 != null) { AcquireTarget(nearestEnemy2.transform); } } return; } // if there's no current target, first look for living enemies latched to attack points within range float shortestDistance = Mathf.Infinity; GameObject chosenEnemy = null; GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag); foreach (GameObject ap in attackPoints) { AttackPoint attackPoint = ap.GetComponent <AttackPoint>(); if (attackPoint != null && !attackPoint.IsVacant()) { float distanceToAP = Vector2.Distance(transform.position, ap.transform.position); if (distanceToAP <= spotRange && distanceToAP < shortestDistance) { shortestDistance = distanceToAP; chosenEnemy = attackPoint.GetOccupant().gameObject; } } } // otherwise, find the nearest enemy if (chosenEnemy == null || (chosenEnemy.GetComponent <Enemy>() != null)) { GameObject[] enemies = GameObject.FindGameObjectsWithTag(Constants.EnemyTag); /*float */ shortestDistance = Mathf.Infinity; //GameObject nearestEnemy = null; foreach (GameObject enemy in enemies) { // if this enemy is not dead if (enemy.GetComponent <Enemy>() != null) { // if the enemy is beyond this unit's spot range, ignore target float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceToEnemy <= spotRange && distanceToEnemy < shortestDistance) { shortestDistance = distanceToEnemy; chosenEnemy = enemy; } } } } if (chosenEnemy != null) { //Debug.Log("FOUND TARGET"); AcquireTarget(chosenEnemy.transform); } else { DismissTarget(); } }
private void Update() { if (!started) { return; } if (coughing) { CoughEffect(); } // update the hit countdown and the replication countdown each frame if (hitCountdown > 0f) { hitCountdown -= Time.deltaTime; } if (replicationCoundtown > 0f && !IsBeingAttacked() && !coughing) { replicationCoundtown -= Time.deltaTime; } if (replicationCoundtown <= 0f && !IsBeingAttacked() && !coughing) { Replicate(); } // if there's a melee unit attacking, // start attacking it (face it, move towards it, and if in range, hit) if (meleeAttackers.Count > 0) { //Debug.Log("attacking melee attacker"); // if it's latched, stop the latched animation if (latched) { attackPoint.SetOccupantActive(false); anim.SetBool("isAttackedWhileLatched", true); anim.SetBool("isMoving", true); anim.SetBool("isAtAP", false); if (!attackedWhileLatched) { attackedWhileLatched = true; } //Debug.Log("stopping latched animation"); //if (anim != null) //{ //anim.SetBool("isLatched", false); //anim.SetTrigger("isAttackedWhileLatched"); //} } AttackMeleeAttacker(); } else // if there's no melee attacker, continue towards the next tile { if (nextTile != null) { //Debug.Log("nextTile != null"); // if already latched, don't move if (latched) { anim.SetBool("isAttackedWhileLatched", false); // unless it's too far away from the attack point; in that case, move towards it if (attackPoint != null && Vector2.Distance(transform.position, attackPoint.transform.position) > 0.15f) { //Debug.Log("move closer to attack point"); attackPoint.SetOccupantActive(false); moveable.MoveDirectlyTowardsPosition(attackPoint.transform.position); anim.SetBool("isAtAP", false); } else { //Debug.Log("starting latched animation"); if (anim != null) { anim.SetBool("isStunned", Shop.instance.IsCoughing()); } if (attackedWhileLatched) { attackedWhileLatched = false; attackPoint.SetOccupantActive(!attackedWhileLatched); } anim.SetBool("isAtAP", true); anim.SetBool("isMoving", false); } } else { //Debug.Log("MoveDirectlyTowardsPosition"); moveable.MoveDirectlyTowardsPosition(nextTile.transform.position); if (Vector2.Distance(transform.position, nextTile.transform.position) <= 0.3f) { // it's reached the tile; go to the next tile, unless the current tile is an attack point AttackPoint ap = nextTile.GetComponent <AttackPoint>(); if (ap != null) { if (ap.IsVacant()) { //Debug.Log("ap != null && ap.IsVacant"); // if it's an attack point and it's still vacant, occupy it ap.SetOccupant(this); attackPoint = ap; latched = true; //anim.SetTrigger("isLatched"); anim.SetBool("isLatched", true); anim.SetBool("isMoving", false); } else // if nextTile is an AP that is occupied, clear visited list and get next tile { //Debug.Log("NEXTTILE IS OCCUPIED AP!!!!!!!! clearing visitedTiles and getting next tile!"); visitedTiles.Clear(); GetNextTile(); } } else // otherwise, continue on the path { VisitTile(nextTile); GetNextTile(); } } } } else { //Debug.Log("nextTile == null; calling GetNextTile()"); GetNextTile(); } } }