- Home /
move enemy to random transform array
Hey guys,
read and watched a good number of tutorials I still seem to be missing something that makes this work properly. Any help would be appreciated.
public class MischiefMonkey : MonoBehaviour {
[SerializeField]
private float _speed = 7f;
[SerializeField]
private Transform[] _treeTopLocations;
void Update()
{
//stay at current locations for 2 seconds
//move to new location
//destroy object after 15 seconds
StartCoroutine(MonkeyMovement());
}
IEnumerator MonkeyMovement()
{
while (GameManager.gameManager.gameOver == false)
{
if (UIManager.uIManager.pauseMenuVisible == true)
{
yield return null;
}
else
{
Transform newTree = TreeTopLocations();
yield return new WaitForSeconds(2);
transform.Translate(newTree.position * _speed * Time.deltaTime);
}
}
}
public Transform TreeTopLocations()
{
int randomIndex = Random.Range(0, _treeTopLocations.Length);
return _treeTopLocations[randomIndex];
}
}
also not entirely sure where to put the destroy object but im less worried about that.
There are multiple places where things go wrong. What is happening when you run the game?
The best way to deter$$anonymous$$e the problem area is to step through your code or put logging in. For example put a Debug.Log call at the start of your $$anonymous$$onkey$$anonymous$$ovement function, in the while loop, in the if statements so you can see if it is even getting the code that gets the tree location. You could also log random Index to see what it is choosing. Once you know more about whats happening post it here
ha ha alright, that's a bit sad.
when i start the game method, the monkey stays put for 2 seconds and then loses its $$anonymous$$d and tries to move, i think, to every available location in the array.
I came up with this by amending a method for instantiating power ups at random points. sadly the instantiation is great but the translate is awful.
Ok so you know it is reaching the transform.Translate code. Which means this code might be working fine, so there is probably something wrong with how you are moving the object.
Answer by Taylor-Libonati · Mar 27, 2019 at 08:36 PM
Ok you have two main problems going on. Your update loop and your translate function. The update loop runs every frame. You are starting a coroutine every frame. That coroutine loops infinitley while you are playing the game. So you are getting an infinite amount of inifite looping code. That will get you some crazy results. Instead you should be starting that coroutine on Awake or Start. Secondly it looks like your translate function is not used properly. You find newTree's position. but then you multiply that position by speed and Time.deltaTime. So you are going to move the object a tiny bit every 2 seconds and not to the actual found position. I suggest doing transform.position = newTree.position. That would instantly teleport the object to the found location. If you get that working then you can figure out how you want to move the object over time instead. Here is what I think you are trying to do in code. I haven't run it so it may have some typos:
using System.Collections;
using UnityEngine;
public class MischiefMonkey : MonoBehaviour {
[SerializeField]
private float _speed = 7f;
private float _closeThreshold = .1f;
[SerializeField]
private Transform[] _treeTopLocations;
//The position we want to move to
private Vector3 _targetPos;
void Awake() {
//Set our first target location to where we already are
_targetPos = transform.position;
//Startup your looping code that finds the target location every few seconds
StartCoroutine(MonkeyMovement());
}
void Update()
{
//If we aren't close to our target location
if(Vector3.Distance(transform.position, _targetPos) > _closeThreshold)){
//Find the direction from where we are to where we want to be
//Normalize it to get a direction rather than the whole distance
Vector3_currentDir = (_targetPos - transform.position).normalized;
//Move towards the target
transform.Translate(_currentDir * _speed * Time.deltaTime);
}
}
IEnumerator MonkeyMovement()
{
while (GameManager.gameManager.gameOver == false)
{
if (UIManager.uIManager.pauseMenuVisible == true)
{
yield return null;
}
else
{
//Dont get a new target for 2 seconds
yield return new WaitForSeconds(2);
//Get a new target
Transform newTree = TreeTopLocations();
_targetPos = newTree.position;
}
}
}
public Transform TreeTopLocations()
{
int randomIndex = Random.Range(0, _treeTopLocations.Length);
return _treeTopLocations[randomIndex];
}
}
so when i change the translate function to the tranform.position = newTree.position, the array index becomes out of range.
hmm. that line of code doesn't even access your array. So I am guessing you are getting an error on line 36? An index out of range error means you are trying to grab an element out of an array in an invalid index. So like if you have 5 elements in your array and you try to grab element 10 that error would throw. The only place you are accessing the array is in your TreeTopLocations function. So I am not sure how adding my line of code could effect that.
I actually see your main problem now though. I will edit my answer to reflect this.
so at line 28 the statement newTree.transform.position is stated as not being declared in the area. I'm not sure if it has anything to do with the method monkeymovement() not being called but thats the only thing throwing it
Sorry I wrote the wrong variable. It should be: Vector3 _currentDir = (_targetPos - transform.position).normalized;
so this is basically working,
it's throwing three problems. the first 2 i can work through on my own.
for some reason lines 36 and 38 both throw the error object reference null. when i remove both those lines and leave the code with no if statements it "runs". So my problem there may just be that i'm missing the references since i'm starting in the play scene rather than the first scene which controls most of the awake functions for the rest of the game. So i'll play around with that.
the problem that's got me stuck is that it will run the coroutine once but then will not try to send it to another location after the specified time.
so from it's first point it will wait 2 seconds and then go to a random location from the array but it will not run it again.
does the set of lines in the update method need to go in the monkey movement method ins$$anonymous$$d somewhere?
No the code in the update is correct. Update runs every frame, and every frame you want the object to animate towards your target. The monkey movement method is code is just to find the next target position every 2 seconds. The reason it is only happening once is probably because you have commented out line 26. The "while" keyword makes something loop until its condition is false. So if you want to comment out line 26 you will need to replace it with: while (true){ This makes it loop forever.
Answer by Nishchhal · Mar 27, 2019 at 09:04 PM
If you wanna move the Monkey towards the target position that you just got from an Array using Translate the you must get a direction Vector pointing towards the target from your current position => (target.transform.position - transform.position).normalize. We normalize to get the magnitude as 1 so you can provide your own speed to manipulate the movement towards a point.
I would suggest you to make a targetfield for monkey and assign that target field from the array and move in the update function towards the target point.
You can put the Destroy Code in making a Timer using IEnumerator or you can do it in Update Loop too.
Hope this helps!
i completely forgot that the destroy code would work in the update function by itself since it happens once the object is first instantiated. THAN$$anonymous$$S
can you give me an example code for the normalize aspect or a link to a tutorial. the normalizing concept is a bit beyond me.
this one is going well on the - transform.position for normalize that helped a lot