Hi, I’m a new Unity user and I can’t find the answer to my specific questions anywhere.
I’m creating a tower defense game where the “enemy” is a ball that rolls along a track.
I’ve followed this great Brakey’s tutorial and everything works fine, I just don’t know how to alter it to have the ball roll along the waypoint path instead of float mid-air.
Here is his code for the Enemy to move from Waypoint to Waypoint for reference:
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float speed = 1.0f;
private int wavepointIndex = 0;
private Transform target;
void Start ()
{
target = Waypoints.points[0];
}
void Update ()
{
Vector3 dir = target.position - transform.position;
transform.Translate(dir.normalized * speed * Time.deltaTime, Space.World);
if (Vector3.Distance(transform.position, target.position) <= 0.05f)
{
GetNextWaypoint();
}
}
void GetNextWaypoint ()
{
if (wavepointIndex >= Waypoints.points.Length - 1)
{
Destroy(gameObject);
return;
}
wavepointIndex++;
target = Waypoints.points[wavepointIndex];
}
}
This example does not implement the waypoint system, but it should be obvious what you need to do.
I’ve taken into account the ball’s radius and speed to make it look more natural while rolling, but the code does not attempt to calculate the radius for you. Measure your objects manually and input an appropriate value.
It ignores the Y position of the target/destination to prevent vertical movement when objects have varying sizes. You can easily disable this if you want.
public class Ball : MonoBehaviour
{
public float speed = 1;
public float radius = 0.5f;
public Transform target;
void Update()
{
Vector3 destinationPositionModified = target.position;
// Uses the ball's Y position instead of destination Y
// to prevent vertical movement
destinationPositionModified.y = this.transform.position.y;
// Used for distance calculation and rotation
Vector3 vectorToDestination = destinationPositionModified - transform.position;
float distance = vectorToDestination.magnitude;
float distanceToTravelOnThisFrame = Mathf.Min (distance, speed * Time.deltaTime);
if (distanceToTravelOnThisFrame > 0)
{
// Move
transform.position = Vector3.MoveTowards (transform.position, destinationPositionModified, speed * Time.deltaTime);
if (radius > 0)
{
// Takes into account the ball's radius
float circumference = 2 * Mathf.PI * radius;
float angularChange = distanceToTravelOnThisFrame / circumference * 360;
// Rolls towards the destination
Vector3 rotationAxis = Quaternion.LookRotation (vectorToDestination) * Vector3.right;
transform.Rotate (rotationAxis, angularChange, Space.World);
}
}
else
{
// Destination reached
// Call GetNextWaypoint() here
}
}
}