How to make an enemy rush the players general direction without using Vector3.MoveTowards

hey guys,

I was wondering how I would make an enemy ai rush a player a bit like the Servants of Cthulu from Terraria. the code is below. what i want to do is make it so that in the attack behavior it rushes in the direction of the player but doesn’t actively follow it, so that it ends up moving in a single direction towards the player. :

public float Health;
public GameObject Target;
public bool canAttack;
public float Dist; //Distance from player
public float Speed;
public float Step;
// Start is called before the first frame update
void Start()
{
    Target = GameObject.FindGameObjectWithTag("Player");
    canAttack = false;
    Health = 100f;
    transform.LookAt(Target.transform);
}

// Update is called once per frame
void Update()
{
    CheckDistance();
    AIBehaviour();
    // temp
    Step = Speed * Time.deltaTime;

}

public void Damage(float Damage)
{
    Health -= Damage;
}

public void CheckHealth()
{
    if (Health <= 0)
    {
        Debug.Log("Enemy Dead");
        Destroy(this.gameObject);
    }
}

public void CheckDistance()
{
    Dist = Vector3.Distance(Target.transform.position, transform.position);
}

public void AIBehaviour()
{
    Step = Speed * Time.deltaTime;
    CheckHealth();
    FlipModel();
    if (!canAttack && Dist > 4)
    {
        MoveTowardsTarget(Target.transform);
    }

    if (Dist < 4)
    {
        AttackPlayer();
    }
    if (canAttack)
    {
        AttackBehaviour();
    }
}

private void MoveTowardsTarget(Transform _target)
{
    transform.position = Vector3.MoveTowards(transform.position, _target.position, Step);
    transform.LookAt(_target);
}

private void AttackPlayer()
{
    canAttack = true;
}

private void AttackBehaviour()
{
    transform.position = Vector3.MoveTowards(transform.position, Target.transform.position, Step * 3);
    Debug.Log("Attack Behaviour");
}

private void FlipModel()
{
    if (Vector3.Distance(transform.position, Target.transform.position) < 0.001f)
    {
        // Swap the position of the cylinder.
        Target.transform.position *= -1.0f;
    }
}

}

Why do you not want to use MoveTowards()?? You can also use Lerp or do it manually, but they will all be ways to get the same thing done. I would stick with trying to figure out how to do it using what you have.


This might be easier to do with a coroutine with a Vector3 parameter relating to the position where the enemy should rush to, not the transform of the target/player.


bool isRushing = false;

void Update()
{
if(Dist < 4 && !isRushing)
{
isRushing = true;
StartCoroutine(EnemyRush(_target.position));
}
}

private IEnumerator EnemyRush(Vector3 targetPos)
{

float step = 0.12f;

while(isRushing)
{
if(step >= (targetPos - transform.position).magnitude)
{
transform.position = targetPos;
isRushing = false;
break;
} 
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
yield return new WaitForEndOfFrame();
}
yield return new WaitForEndOfFrame();
}

That is a bit of untested code, but it should get you what you need.