- Home /
How to make object move from one random point to another continuously?
Student new to coding so sorry if my code doesn't make much sense! In my set up I currently have a giant cube that has this script(JS) attached to it:
public var prefab: Transform;
function Update () {
if(Input.GetMouseButtonDown(0)){
Instantiate(prefab, new Vector3(0, 0, 3), Quaternion.identity);
}
}
So when clicked a sphere is spawned and dropped onto a plane below. When spawned I want these spheres to move to a random coordinate along the plane, then once it gets there to move to another random point. Here is what I have:
var speed: float;
var arrived: boolean;
var randX: float;
var randZ: float;
var newPosition;
function Start(){
arrived = false;
randX = Random.Range(-5, 5);
randZ = Random.Range(-5, 5);
newPosition = new Vector3(randX, -1.504, randZ);
}
function Update () {
if(!arrived) {
transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * speed);
if(GameObject.Find('SpawnedObj').transform.position.x == randX) {
arrived = true;
randX = Random.Range(-5, 5);
randZ = Random.Range(-5, 5);
newPosition = new Vector3(randX, -1.504, randZ);
};
};
else if(arrived){
// WaitForSeconds(1);
arrived = false;
};
}
As you can probably tell when I run this the sphere moves to the initial random coordinate, but then doesn't move after that. How can I fix this? Also I want to have it so that when it reaches the coordinate it waits a few seconds before moving to the next, but I don't know how to do that. I dabbled with WaitForSeconds, but if thats the right way to go I don't think I used it correctly. Any kind of help would be greatly appreciated!
UPDATE:
So as I was messing around with it some more on my own I changed the GameObject.Find('SpawnedObj').transform.position.x to just transform.position.x and then changed speed from 1 to 50. What I noticed is it would then move from point to point, but at seemingly random intervals. When speed is changed back to 1 it will not move from its initial random point. I have no idea why this is. Help in any form will still be appreciated!
Answer by Legend_Bacon · Oct 30, 2017 at 07:25 PM
Hello there,
To preface this, I don't code in JS, so hopefully you'll be able to use my C# for your stuff. While you could in theory achieve what you want within an update loop, I would strongly recommend using a coroutine for this. More info HERE.
The "WaitForSeconds", as far as I know, works best when used in coroutines, but won't work if you just stick it in an update.
Basically, drag this script onto your sphere and it should work:
using System.Collections;
using UnityEngine;
public class testScript : MonoBehaviour
{
private float movementDuration = 2.0f;
private float waitBeforeMoving = 2.0f;
private bool hasArrived = false;
private void Update()
{
if(!hasArrived)
{
hasArrived = true;
float randX = Random.Range(-5.0f, 5.0f);
float randZ = Random.Range(-5.0f, 5.0f);
StartCoroutine(MoveToPoint(new Vector3(randX, -1.504f, randZ)));
}
}
private IEnumerator MoveToPoint(Vector3 targetPos)
{
float timer = 0.0f;
Vector3 startPos = transform.position;
while (timer < movementDuration)
{
timer += Time.deltaTime;
float t = timer / movementDuration;
t = t * t * t * (t * (6f * t - 15f) + 10f);
transform.position = Vector3.Lerp(startPos, targetPos, t);
yield return null;
}
yield return new WaitForSeconds(waitBeforeMoving);
hasArrived = false;
}
}
If you want or need more info on cool ways to Lerp stuff, THIS is a great read.
I hope this helps!
~LegendBacon
Thanks for the reply, and thanks for the reads! I'll fiddle around with this in JS when I get home from class and let you know how it works/if I have any issues. I'm definitely gonna learn C# after this week, seems to be more support for it.
I would recommend switching to C# yes, as Unity is dropping JS soon anyways. Best of luck!
~LegendBacon
Works like a charm! Only thing I'm wondering is what to do when there are many of them and they collide, as it seems to throw it all off. Perhaps an if statement where if they come in contact with each other it kills and restarts the code? Do you think that will work?
Hello there,
A fair point here, I didn't consider collisions. In that case, if you need to stop the coroutine immediately, you can always assign it to a variable and stop that:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScript : $$anonymous$$onoBehaviour
{
private float movementDuration = 2.0f;
private float waitBefore$$anonymous$$oving = 2.0f;
private bool hasArrived = false;
private Coroutine moveCoroutine = null;
private void Update()
{
if (!hasArrived)
{
hasArrived = true;
float randX = Random.Range(-5.0f, 5.0f);
float randZ = Random.Range(-5.0f, 5.0f);
moveCoroutine = StartCoroutine($$anonymous$$oveToPoint(new Vector3(randX, -1.504f, randZ)));
}
if (Input.Get$$anonymous$$ouseButtonDown(0))
Stop$$anonymous$$ovement();
}
private IEnumerator $$anonymous$$oveToPoint(Vector3 targetPos)
{
float timer = 0.0f;
Vector3 startPos = transform.position;
while (timer < movementDuration)
{
timer += Time.deltaTime;
float t = timer / movementDuration;
t = t * t * t * (t * (6f * t - 15f) + 10f);
transform.position = Vector3.Lerp(startPos, targetPos, t);
yield return null;
}
yield return new WaitForSeconds(waitBefore$$anonymous$$oving);
hasArrived = false;
}
private void Stop$$anonymous$$ovement()
{
if (moveCoroutine != null)
StopCoroutine(moveCoroutine);
}
public void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("sphereTag"))
Stop$$anonymous$$ovement();
}
}
You can assign a coroutine to a variable by doing myCoroutineVariable = StartCoroutine($$anonymous$$yCoroutine());
. Then, whenever you want to stop the coroutine, you can call StopCoroutine(myCoroutineVariable)
.
In this script, I do it on mouse input or when the sphere collides with an object that has the tag "sphereTag". Note that it immediately stop the coroutine, which means the "hasArrived" doesn't get set back to false.
If you need more info about collision events, I encourage you to take a look at THIS handy tutorial right here.
Hope that helps! ~LegendBacon
Hi I know this is a pretty old post. $$anonymous$$ay I ask, what if I do not want the sphere to move indefinitely ie, stops after 3 random movement? Should I use a while loop ? If so which part of the code should i add the while loop in? :( thank you @Legend_Bacon
Your answer
Follow this Question
Related Questions
Semi Random Monster Spawner 3 Answers
using Switch and Case for 50% chance of occurance? C# 3 Answers
Teleporting camera and gameobjekt togather at random? 0 Answers
how to make 3d objects appear randomly? 2 Answers