I am trying to move an enemy object to a set destination on a straight line. He will be walking to this destination. I have a GameController script that is attached to an empty GameObject called GameController which spawns the enemies. All the enemies are spawned at this GameObject position and I want them to walk in a straight line towards a destination(not just magically teleport there.) I can’t seem to get the code to work. The instantiated enemy objects just stand there at the GameController object location and don’t move at all. I tried different values for the last parameter of Vector3.MoveTowards, nothing seems to work.
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour {
public GameObject enemy;
private GameObject enemyInstance;
Transform enemyWaypoint1;
// Use this for initialization
void Start () {
StartCoroutine(enemySpawn());
enemyWaypoint1.position = new Vector3(-5.19f, -3.91f, 0);
}
// Update is called once per frame
void Update () {
}
IEnumerator enemySpawn()
{
while (true)
{
yield return new WaitForSeconds(2.0f);
Vector3 spawnPosition = new Vector3(transform.position.x, transform.position.y, 0);
enemyInstance = (GameObject) Instantiate(enemy, spawnPosition, Quaternion.identity);
enemyInstance.transform.position = Vector3.MoveTowards(transform.position, enemyWaypoint1.position, 5);
yield return new WaitForSeconds(Random.Range(1, 2));// Prevents infinite loop crashing.
}
}
This is a 2D game. The position that I want all the enemies to move to is fixed and will never change hence why I declared the enemyWaypoint1.position.
You only call MoveTowards once, it need to be called repeatedly. Each time you call it, it will move a bit more towards the destination (where the final parameter is the maximum distance it will move each time it is invoked).
No, you want to call the method once, either in Update or FixedUpdate. Place a script with the movement code on your prefab. You should be able to use the code from the example for MoveTowards.
public Transform waypoint1;
public float speed;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, waypoint1.position, step);
}
One more thing, how would I go about adding additional waypoints. For example, once the enemy has moved to waypoint 1, I then want it to climb an incline towards a waypoint2. Would this be the correct way of approaching it(in Update())
EDIT: It doesn’t seem to be working. The enemy gets to waypoint 1 and then stops. Here is the code I am running:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour {
public Transform waypoint1;
public Transform waypoint2;
public float speed;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, waypoint1.position, step);
if(transform.position.x >= waypoint1.position.x)
{
transform.position = Vector3.MoveTowards(transform.position, waypoint2.position, step);
}
}
}
In your code, the “MoveTowards” on line 19 will still be hit every frame, even after he reaches that position. So your player will keep moving back towards waypoint1 every frame, even if line 23 moves him towards waypoint2.
A good way to handle this would be to keep an array of Transforms for all the waypoints (in order), and perhaps an int variable index for the current destination.
So in your Update, you always move towards waypoints[currentWaypointIndex].position. When he reaches that position, you do “currentWaypointIndex++” to get a new destination. Just make sure that the index doesn’t go out of range when you run out of waypoints.