1
\$\begingroup\$

I am trying to make a bullet hell game. I want my 2D enemies to move in predefined, curving patterns. How should I do this?

The difficulty I have is being able to quickly produce enemy movements that are

(A) predefined, not random

(B) curved

(C) easy to make, with little coding

(D) visually able to see what is going on, maybe in the inspector?

Perhaps a 3rd party tool may be warranted?

\$\endgroup\$
3

1 Answer 1

1
\$\begingroup\$

Since you've asked for a solution that involves little coding, I'd suggest using linked prefabs. The idea is to build a "library" of simple maneuvers and then chain them.
Pseudocode below, followed by an explanation:

"Move" class to represent a single maneuver:

public Vector2 velocity;  
public float angularVelocity;  
public float duration;  

void execute(float stepSize, Transform avatar) {  
  //move avatar, e.g. avatar.Translate(avatar.forward * velocity * stepSize);  
  //rotate avatar  
}

"MoveSet" class to represent an enemy's course:

public Vector2 spawnOffset; //optional, but if you need this, best put it here  
public Move[] moves;  
private int currentMove = 0;
private float moveTime;  

bool execute(float stepSize, Transform avatar) {  
  moves[currentMove].execute(stepSize, avatar);  
  moveTime += stepSize;  
  if (moveTime >= moves[currentMove].duration) {  
    currentMove += 1;  
    moveTime = 0;  
    if (currentMove >= moves.Length)  
      return true; //move set finished - repeat set or despawn enemy etc.  
  }  
  return false;  
}  

In your enemy class, add a public MoveSet variable and call

myMoveSet.execute(time.fixedDeltaTime, gameObject.transform)  

from FixedUpdate.

In your Move's and MoveSet's OnDrawGizmosSelected, call execute in a loop with a suitable step size and e.g. a Debug.DrawLine(lastPosition, transform.position) call after each step. Reset position after the loop.

How you'd use this:

  1. Create empty GameObject, add "Move" script. The editor should draw an approximation of the path. Fine tune variables until you're satisfied, then save as prefab.

  2. After you have a few "Move" prefabs, create a GameObject with a "MoveSet" component, drag "Move" prefabs into the array until you're satisfied with the course, then save as prefab as well.

  3. Drag a "MoveSet" onto an enemy or assign at runtime. Spawn an instance of the "MoveSet" prefab before using it.

You'll probably have to expand this a little to suit your project, perhaps apply forces to a Rigidbody instead of moving directly, tweaking performance etc, but this should give you an idea of where to start.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .