i am working on a unity project for school and i am currently stuck on the step of making an object move back and forth between 2 waypoints. the best ive been able to do so far is just make it move one way, but i dont know how to make it go back and then repeat the cycle. please help i am extremely stressed out
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjSpawnerScript : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] GameObject ballPrefab;
int waypointIndex = 0;
// Start is called before the first frame update
void Start()
{
// starting position.
transform.position = waypoints[0].transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
void Move()
{
if (waypointIndex <= waypoints.Count - 1)
{
//save the current waypoint in targetPosition
//targetPosition: where we want to go
var targetPosition = waypoints[waypointIndex].transform.position;
//to make sure z position is 0
targetPosition.z = 0f;
var movementThisFrame = 5.0f * Time.deltaTime;
//move from the current position, to the target position, the maximum distance one can move
transform.position = Vector2.MoveTowards(transform.position, targetPosition, movementThisFrame);
//if we reached the target waypoint
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
}
private void spawnBall()
{
Instantiate(ballPrefab, transform.position, Quaternion.identity);
}
}
i am working on a unity project for school and i am currently stuck on the step of making an object move back and forth between 2 waypoints. the best ive been able to do so far is just make it move one way, but i dont know how to make it go back and then repeat the cycle. please help i am extremely stressed out
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjSpawnerScript : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] GameObject ballPrefab;
int waypointIndex = 0;
// Start is called before the first frame update
void Start()
{
// starting position.
transform.position = waypoints[0].transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
void Move()
{
if (waypointIndex <= waypoints.Count - 1)
{
//save the current waypoint in targetPosition
//targetPosition: where we want to go
var targetPosition = waypoints[waypointIndex].transform.position;
//to make sure z position is 0
targetPosition.z = 0f;
var movementThisFrame = 5.0f * Time.deltaTime;
//move from the current position, to the target position, the maximum distance one can move
transform.position = Vector2.MoveTowards(transform.position, targetPosition, movementThisFrame);
//if we reached the target waypoint
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
}
private void spawnBall()
{
Instantiate(ballPrefab, transform.position, Quaternion.identity);
}
}
Share
Improve this question
asked Mar 23 at 22:10
zlz1zlz1
1
4
|
1 Answer
Reset to default 1Your code is almost working, but you're using Vector2.MoveTowards (note that you're using Vector2, not Vector3), which causes Unity to ignore the z-axis. Are you sure you want the z-axis to be zeroed out? Why couldn't you use Vector3 instead, given that your points in the scene are already positioned correctly?
Secondly, this code isn't designed for the points to move during gameplay; the object's movement will break. As a solution, I propose the following code that allows the object to move even when the points change their positions over time. As a bonus, I've added lines that let you see the object's trajectory in the editor.
Also remember that if you want an object to move from one point to another and back, you need to reset the end point when the end of the path is reached.
using System.Collections.Generic;
using UnityEngine;
public class TestScript : MonoBehaviour
{
[SerializeField] private List<Transform> _points;
[SerializeField] private float _speed = 10f;
private int _currentPointIndex = 0;
private void OnEnable()
{
// Set the initial position of the object
_currentPointIndex = 0;
transform.position = _points[0].position;
}
private void Update()
{
Move();
DebugDraw();
}
private void Move()
{
transform.position = Vector3.MoveTowards(transform.position, CurrentTarget, Time.deltaTime * _speed);
if (transform.position == CurrentTarget) GetNextTarget();
}
private Vector3 CurrentTarget => _points[_currentPointIndex].position;
private void GetNextTarget()
{
// There can't be less than one point!
if (_points.Count <= 1) throw new System.Exception("Not enough points!");
// If there is no next point, return to the starting point
_currentPointIndex++;
if (_points.Count <= _currentPointIndex)
_currentPointIndex = 0;
}
private void DebugDraw()
{
for (int i = 1; i < _points.Count; i++)
Debug.DrawLine(_points[i - 1].position, _points[i].position, Color.blue);
// The line between the first and last points will be red
if (_points.Count > 2)
Debug.DrawLine(_points[^1].position, _points[0].position, Color.red);
}
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744267023a4565915.html
Vector2.MoveTowards
can guarantee hitting the target. – shingo Commented Mar 24 at 5:04waypointIndex
to 0 when it is out of bound, so that the ball can go to the first way point when it reaches the last one. – shingo Commented Mar 24 at 5:07