Hi! I have a problem with my 2D mobile game. There is a SeekPlayer() function that as it states - makes the enemy seek the player. There is also FollowPlayer() (when enemy finds the player, it starts chasing him). However when the enemy hits (collides) with the player, the enemy gets knocked back. However it makes the enemy jiggle (or vibrate - however u want to call it). I know that it’s because 2 forces are applied at the same time (FollowPlayer() is working simultaneously with the Knockback function). Here is the code of 2 functions that make it work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthManager : MonoBehaviour
{
public Image healthBar;
public float healthAmount = 100f;
private Rigidbody2D enemyRb;
private Rigidbody2D bossRb;
void Start()
{
enemyRb = GameObject.FindGameObjectWithTag("enemy").GetComponent<Rigidbody2D>();
bossRb = GameObject.FindGameObjectWithTag("Demon Wolf").GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
}
// Obsługuje kolizje 2D
private void OnCollisionEnter2D(Collision2D collision)
{
// Używamy 'collision.collider' do sprawdzenia kolizji z obiektem przeciwnika
if (collision.gameObject.tag == "enemy")
{
NormalHealthLoss();
PushEnemyBack(collision);
}
else if (collision.gameObject.tag == "Demon Wolf")
{
BossHealthLoss();
PushBossBack(collision);
}
}
void NormalHealthLoss()
{
float damage = 10f;
healthAmount -= damage;
// Ustawienie fillAmount paska zdrowia
healthBar.fillAmount = healthAmount / 100f;
if (healthAmount <= 0)
{
YouLost();
}
}
void BossHealthLoss()
{
float damage = 20f;
healthAmount -= damage;
healthBar.fillAmount = healthAmount / 100f;
if (healthAmount <= 0)
{
YouLost();
}
}
void YouLost()
{
}
void PushEnemyBack(Collision2D collision)
{
Vector2 pushDirection = collision.transform.position - transform.position;
pushDirection.Normalize();
if (enemyRb != null)
{
float pushStrength = 5f;
enemyRb.AddForce(pushDirection * pushStrength, ForceMode2D.Impulse);
enemyRb.drag = 0.6f;
}
}
void PushBossBack(Collision2D collision)
{
Vector2 pushDirection = collision.transform.position - transform.position;
pushDirection.Normalize();
if (bossRb != null)
{
float pushStrength = 5f;
bossRb.AddForce(pushDirection * pushStrength, ForceMode2D.Impulse);
bossRb.drag = 0.7f;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class EnemyAI : MonoBehaviour
{
public Transform Player;
public float speed = 4f;
private float followRange = 10.0f;
public float seekRadius = 10.0f;
// boole powpierdalac zeby nie scinalo enemy kurwa mac
float mapMinY = -30f;
float mapMaxY = 30f;
float mapMaxX = 30;
float mapMinX = -30;
Vector2 targetPosition;
bool IsPlayerVisible;
bool isSeeking = false;
void Start()
{
}
// Update is called once per frame
void Update()
{
float distance = Vector2.Distance(transform.position, Player.position);
if (distance > followRange)
{
IsPlayerVisible = false;
SeekPlayer();
}
else if (distance <= followRange)
{
IsPlayerVisible = true;
FollowPlayer();
}
}
void SeekPlayer()
{
// Wciąż musimy "szukać" w danym promieniu, nawet jeśli gracz nie jest w zasięgu.
if (!isSeeking)
{
// Wygeneruj losowy punkt w promieniu seekRadius
Vector2 randomDirection = new Vector2(
Random.Range(-seekRadius, seekRadius),
Random.Range(-seekRadius, seekRadius));
// Ustaw nowy cel w zależności od kierunku
targetPosition = (Vector2)transform.position + randomDirection;
// Upewnij się, że cel jest w granicach mapy
if (!IsWithinMapBounds(targetPosition))
{
// Jeśli cel wykracza poza mapę, ustaw go na dozwolonym obszarze
targetPosition = new Vector2(Mathf.Clamp(targetPosition.x, mapMinX, mapMaxX), Mathf.Clamp(targetPosition.y, mapMinY, mapMaxY));
}
isSeeking = true;
}
// Ruch w stronę losowego celu
if (Vector2.Distance(transform.position, targetPosition) > 0.5f) // Jeśli jesteśmy dalej niż 0.5 jednostki
{
transform.position = Vector2.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
else
{
// Kiedy dotrzemy do celu, zresetuj isSeeking, żeby znowu poszukać nowego punktu
isSeeking = false;
}
}
void FollowPlayer()
{
if (IsPlayerVisible)
{
transform.position = Vector2.MoveTowards(transform.position, Player.position, speed * Time.deltaTime);
}
}
bool IsWithinMapBounds(Vector2 position)
{
return position.x >= mapMinX && position.x <= mapMaxX &&
position.y >= mapMinY && position.y <= mapMaxY;
}
}