Number is randomizing repeatedly per click - c#

I am currently working on a mini-game that revolves around numbers randomizing and score being allocated depending on whether the number displayed is a multiple of 'x' in this case 3.
However, I have an issue, because for some reason whenever the player clicks to randomize, it randomizes several times completely throwing my score system.
So far, I have attempted to solve this issue through the use of:
yield return new WaitForEndOfFrame();
However, this proved to be for naught as it did not help.
If any of you could shed some light on why this is happening it would be deeply appreciated.
Code in use
void Awake ()
{
randomNumber = Random.Range (0, 36);
}
void Start()
{
mycam = Camera.main;
}
void FixedUpdate()
{
StartCoroutine(Selection ());
thisAnswer.text = randomNumber.ToString ();
}
// Update is called once per frame
void Update ()
{
if (CorrectCount == 5)
{
PlayerPrefs.SetInt ("MiniScore", miniScore);
Destroy (GameObject.Find ("Killswitch"));
}
}
IEnumerator Selection ()
{
Ray ray = mycam.ScreenPointToRay (Input.mousePosition);
if (Input.GetKey (KeyCode.Mouse0))
{
if (Physics.Raycast (ray, out hit))
{
if(hit.transform.tag == "answer")
{
if (System.Convert.ToInt32(thisAnswer.text) % 3 == 0)
{
miniScore = miniScore + 100;
CorrectCount = CorrectCount + 1;
yield return new WaitForEndOfFrame();
randomNumber = Random.Range (0, 36);
Debug.Log (miniScore.ToString());
}
else if (System.Convert.ToInt32(thisAnswer.text) % 3 != 0)
{
if (miniScore > 50)
{
miniScore = miniScore - 50;
}
else if (miniScore < 50)
{
miniScore = 0;
}
Debug.Log (miniScore.ToString ());
yield return new WaitForEndOfFrame();
randomNumber = Random.Range (0, 36);
}
}
}
}
}

I suspect whats happening here is that this line of code
if (Input.GetKey (KeyCode.Mouse0))
is getting executing several times a once the user presses the mouse button - GetKey will return true as long as the button is down (which is will be for several frames - So you could try
if (Input.GetKeyUp (KeyCode.Mouse0))
This should only fire once when the mouse button is released.
Check out
http://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html

Related

why is every second "if input.axis" statement is failing without error when trying to detect a RayCastHit?

I am creating a 3D top-down game and I am wanting to make a character move around though i am using ray casts to make sure that when the characters collides it does continue to change it's position when the character is trying to move against it.
I have create code such as:
[SerializeField] private float speed = 5;
public float XMovement;
public float ZMovement;
public Vector3 RotationY;
void FixedUpdate()
{
MovementSetting();
var dir = new Vector3(XMovement, 0, ZMovement);
transform.Translate(dir * speed * Time.deltaTime);
}
void MovementSetting()
{
var ray = new Ray();
RaycastHit hit;
// If input is "a"
if (Input.GetAxis("Horizontal") < 0)
{
RotationY = transform.TransformDirection(Vector3.left);
ray = new Ray(this.transform.position, RotationY);
if (Physics.Raycast(ray, out hit, 0.6f)) { XMovement = 0; }
else { XMovement = Input.GetAxis("Horizontal"); }
}
else { XMovement = 0; }
// If input is "d"
if (Input.GetAxis("Horizontal") > 0)
{
RotationY = transform.TransformDirection(Vector3.right);
ray = new Ray(this.transform.position, RotationY);
if (Physics.Raycast(ray, out hit, 0.6f)) { XMovement = 0; }
else { XMovement = Input.GetAxis("Horizontal"); }
}
else { XMovement = 0; }
// If input is "s"
if (Input.GetAxis("Vertical") < 0)
{
RotationY = transform.TransformDirection(Vector3.back);
ray = new Ray(this.transform.position, RotationY);
if (Physics.Raycast(ray, out hit, 0.6f)) { ZMovement = 0; }
else { ZMovement = Input.GetAxis("Vertical"); }
}
else { ZMovement = 0; }
// If input is "w"
if (Input.GetAxis("Vertical") > 0)
{
RotationY = transform.TransformDirection(Vector3.forward);
ray = new Ray(this.transform.position, RotationY);
if (Physics.Raycast(ray, out hit, 0.6f)) { ZMovement = 0; }
else { ZMovement = Input.GetAxis("Vertical"); }
}
else { ZMovement = 0; }
}
in theory this is meant to work though, only every second "if input" statement 100% works
I find that as soon as it reaches if (Physics.Raycast(ray, out hit, 0.6f)) for every odd "if input", it stops working, though doesn't throw an error code
I tried using debug.log to see if there was any response in the "if physics" respone which I didn't get.
I also tried (dumb idea) seeing if I double the "if input" statements twice, therefore every second one should work, that didn't work either
They are not failing. But the second if-statement may revert the XMovement the first one sets:
// Let's assume the horizontal axis is < 0 ...
if (Input.GetAxis("Horizontal") < 0) {
XMovement = ...; // ... then a value will be assigend here.
} else {
XMovement = 0;
}
if (Input.GetAxis("Horizontal") > 0) {
// We said it's < 0, so this code will not be executed
} else {
XMovement = 0; // however, this one will
// and thus the value we assigned earlier will be cleared!
}
Let's re-organize the code
float horizontalAxis = Input.GetAxis("Horizontal");
if (horizontalAxis < 0) {
XMovement = ...;
} else if (horizontalAxis > 0) {
XMovement = ...;
} else { // horizontalAxis == 0
XMovement = 0;
}
Now, always exactly one branch will ever be executed.
You are using else conditions and then creating a conditional asking for the case that is already entering in the else, this is making you get the impression that "odd" things work, just remove your "else's" and put it inside a condition to check if the value is 0

Unity: Switching from one FixedUpdate-like coroutine to another one

I have a coroutine DefaultFixedUpdate() that functions as a replacement for FixedUpdate() and another coroutine called WallSlidingFixedUpdate(). I have two variables that store which of the both is active. activeCoroutine and prevActiveCoroutine with the starting strings nameof(DefaultFixedUpdate) and "no coroutine". In FixedUpdate() from Unity I have this code that should change coroutines if activeCoroutine and prevActiveCoroutine are not the same:
void FixedUpdate()
{
if (activeCoroutine != prevActiveCoroutine)
{
print($"changing coroutines from {prevActiveCoroutine} to {activeCoroutine}");
StopCoroutine(prevActiveCoroutine);
StartCoroutine(activeCoroutine);
prevActiveCoroutine = activeCoroutine;
print("changed coroutines");
}
}
When starting the game DefaultFixedUpdate() starts as expected and prevActiveCoroutine changes as expected to activeCoroutine and when a condition inside DefaultFixedUpdate() is met to switch to WallSlidingFixedUpdate() activeCoroutine changes to the new string as expected. But when StartCoroutine(activeCoroutine) gets called the code inside WallSlidingFixedUpdate() doesn't run for some reason. StopCoroutine(prevActiveCoroutine) does work. The end result is that none of the two corutines runs but expected was that WallSlidingCoroutine() runs.
These are the two Coroutines. The changing of activeCoroutine happens almost at the bottom of both functions.
IEnumerator DefaultFixedUpdate()
{
while (true)
{
//setup
gravity = (velocity.y < 0 || !Input.GetKey(KeyCode.Space)) ? dropGravity : normalGravity;
Vector2 pos = transform.position + col.size.y * 0.5f * Vector3.up;
Vector2 timeStepVelocity = velocity * Time.fixedDeltaTime;
Vector2 pos1 = pos;
velocity.y -= gravity * Time.fixedDeltaTime;
//checking collision
RaycastHit2D[] colChecks = Physics2D.BoxCastAll(pos, col.size, 0, timeStepVelocity, timeStepVelocity.magnitude, 0b1000000);
//remove unwanted collisions that are behind and don't make sense to collide with
List<RaycastHit2D> newColChecks = new();
foreach (RaycastHit2D colCheck in colChecks)
if (Vector2.Dot(colCheck.normal, timeStepVelocity) < 0)
newColChecks.Add(colCheck);
colChecks = newColChecks.ToArray();
//remove unwanted velocities
foreach (RaycastHit2D colCheck in colChecks)
{
if (Mathf.Abs(colCheck.normal.x / colCheck.normal.y) > 1) // left and right
{
velocity.x = Mathf.Sign(colCheck.normal.x) > 0 ? Mathf.Max(velocity.x, 0) : Mathf.Min(velocity.x, 0);
}
else // top bottom
{
velocity.y = Mathf.Sign(colCheck.normal.y) > 0 ? Mathf.Max(velocity.y, 0) : Mathf.Min(velocity.y, 0);
}
}
//calculate correct destination
if (colChecks.Length == 0)
pos += timeStepVelocity;
else
{
//create bounding box for all possible future positions
Vector4 posBox = new Vector4(pos.x, pos.x + timeStepVelocity.x, pos.y, pos.y + timeStepVelocity.y);
//move to surface
pos = colChecks[0].centroid;
//slide along surface until hitting another tangent or the bounding box
Vector2 tangent = new Vector3(colChecks[0].normal.y, -colChecks[0].normal.x);
Vector2 centroid = pos;
//slide until hitting distance bounds
if (Mathf.Abs(tangent.x) > Mathf.Abs(tangent.y)) //top and bottom
{
pos += tangent / tangent.x * (timeStepVelocity.x - pos.x + pos1.x);
tangent = Mathf.Sign(centroid.y - pos1.y) * tangent;
}
else //left and right
{
pos += tangent / tangent.y * (timeStepVelocity.y - pos.y + pos1.y);
tangent = Mathf.Sign(centroid.x - pos1.x) * tangent;
}
//save previous surface that is being slid on
Vector2 prevTangent = Tangent(colChecks[0].normal);
//check if I collided with another tangent along the way
colChecks = Physics2D.BoxCastAll(centroid, col.size, 0, pos, Vector2.Distance(pos, centroid), 0b1000000);
//remove unwanted collisions that are behind and don't make sense to collide with
newColChecks = new();
foreach (RaycastHit2D colCheck in colChecks)
if (Vector2.Dot(colCheck.normal, tangent * Mathf.Sign(Vector2.Dot(pos - centroid, tangent))) < 0 || Vector2.Dot(colCheck.normal, timeStepVelocity) < 0)
newColChecks.Add(colCheck);
colChecks = newColChecks.ToArray();
if (colChecks.Length > 1)
{
pos = centroid + (pos - centroid).normalized * colChecks[1].distance;
}
//repeat
int loopBreak = 0;
string loopBreakMessage = "";
while (true)
{
loopBreakMessage += centroid + "\n";
if (loopBreak > 4)
{
Debug.LogError("loop limit exceeded\n" + loopBreakMessage);
break;
}
loopBreak++;
//check if I collided with another tangent along the way
colChecks = Physics2D.BoxCastAll(centroid, col.size, 0, pos - centroid, Vector2.Distance(pos, centroid), 0b1000000);
//remove unwanted collisions that are behind and don't make sense to collide with
newColChecks = new();
foreach (RaycastHit2D colCheck in colChecks)
if (Tangent(colCheck.normal) != prevTangent)
newColChecks.Add(colCheck);
colChecks = newColChecks.ToArray();
if (colChecks.Length > 2)
{
prevTangent = colChecks[0].normal;
if (!VectorOnSameQuarter(colChecks[1].normal, colChecks[2].normal)) // stuck in a corner
{
pos = centroid + (pos - centroid).normalized * colChecks[2].distance;
break;
}
else //continue along new tangent
{
//corner pos
centroid += (pos - centroid).normalized * colChecks[2].distance;
//end pos if there's no surface along the way
pos = PosAlongVectorInsideRectangle(posBox, centroid, Tangent(colChecks[2].normal));
}
}
else
{
break;
}
}
AlignVelocityWithGround();
}
//check if player is grounded and save ground tangent to remove small hops when going down slopes
PlayerState.OnGround = false;
RaycastHit2D[] jumpChecks = Physics2D.BoxCastAll(pos, col.size, 0, Vector2.down, 1e-3f, 0b1000000);
if (jumpChecks.Length != 0)
{
foreach (RaycastHit2D jumpCheck in jumpChecks)
{
if (jumpCheck.normal.y > Mathf.Abs(jumpCheck.normal.x))
{
PlayerState.OnGround = true;
groundTangent = new Vector2(jumpCheck.normal.y, -jumpCheck.normal.x);
}
}
PlayerState.state = PlayerState.state == PlayerState.State.WallSliding ? PlayerState.State.Default : PlayerState.state;
//check for a wall slide and save wall tangent for smooth sliding
if (!PlayerState.OnGround && velocity.y < 0 && Mathf.Abs(jumpChecks[0].normal.x) > Mathf.Abs(jumpChecks[0].normal.y) && Mathf.Asin(jumpChecks[0].normal.y) * Mathf.Rad2Deg < 15)
{
groundTangent = new Vector2(jumpChecks[0].normal.y, -jumpChecks[0].normal.x);
transform.position = pos - col.size.y * 0.5f * Vector2.up;
activeCoroutine = nameof(WallSlidingFixedUpdate);
yield break;
}
}
transform.position = pos - col.size.y * 0.5f * Vector2.up;
yield return new WaitForFixedUpdate();
}
}
IEnumerable WallSlidingFixedUpdate()
{
print("wallsliding coroutine entered");
while (true)
{
print("wallsliding coroutine happening");
Vector2 pos = transform.position;
pos -= Time.fixedDeltaTime * wallSlideSpeed * groundTangent / groundTangent.y;
transform.position = pos;
if (InputManager.Left && groundTangent.y > 0)
{
activeCoroutine = nameof(DefaultFixedUpdate);
yield break;
}
else if (InputManager.Right)
{
activeCoroutine = nameof(DefaultFixedUpdate);
yield break;
}
yield return new WaitForFixedUpdate();
}
}
You figured your issue about the return type out already -> It needs to be IEnumerator.
Anyway my question is WHY?
Instead of going through all that trouble for switching between different Coroutine instances via a string I would rather have only a single outer scope routine running and then rather switch between which inner block to execute
private enum RoutineType
{
Default,
WallSliding
}
private RouineType activeRoutine;
private IEnumerator FixedUptadeRoutine()
{
while(true)
{
switch(activeRoutine)
{
case RoutineType.WallSliding:
yield return DefaultRoutine();
break;
case default:
yield return WallSlidingRoutine();
break;
}
}
}
private IEnumerator DefaultRoutine()
{
while(true)
{
// NOTE: Btw you want to wait for fixed update FIRST
// Before applying all the values
...
// And now this will simply make sure you change the routine type
activeRoutine = RoutineType.WallSliding;
// and exit this one so the outer routine will handle the switch in the next frame
yield break;
...
}
}
private IEnumerator WallSlidingRoutine()
{
...
}
you can simply yield return any IEnumerator so it will be executed and at the same time the outer routine waits for it to finish. There is no need to have multiple start and stop coroutines.
Holy moly, how did I miss this. The return value of WallSlidingFixedUpdate is IEnumerable and not IEnumerator. I changed it to IEnumertor and now it works.

How to increment/decrement only by one when Ray hits

So, the game is to find a difference. When ray hits a collider of hidden object, it is supposed to add a score only of one and reduce a private integer differences value by one. But when the ray hits an object collider it is constantly incrementing/decrementing while the ray is hitting the collider. How can i change that? It is in the following method:
void Update()
{
camRay = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
Debug.DrawRay(camRay.origin, camRay.direction, Color.red, 1);
if (Input.touchCount > 0)
{
if (Physics.Raycast(camRay, out result))
{
/*{
obj = result.collider.gameObject;
score = score + 1;
differences= differences - 1;
score1.text = " " + score;
predmet.Play();
}*/
if (result.collider.CompareTag("Slike") && !hitOnce)
{
score +=1;
differences-= 1;
score1.text = " " + score;
predmet.Play();
}
else
{
hitOnce = false;
}
if (differences == 0)
{
WinPanel.SetActive(true);
}
}
}
}
When you first hit the object, you could remove or disable it's collider component. This should prevent it from being hit by more Raycasts.
On first hit, something like:
result.collider.enabled = false;

I cannot get my player to move twice in a row

Sorry if the question seems vague but I am creating a turn based, 2D roguelike game for coding practice and want the player to be able to move twice while the enemy moves once when the user clicks a button. I have tried using multiple booleans but to no avail.
The players turn is an integer which once it reaches 0, it becomes the enemies turn. The code for when the user clicks the button:
public void ButtonClicked()
{
GameManager.instance.playersTurn = 2;
}
the movement code inside my player manager(this is where the error lies)
void Update () {
if (0 > GameManager.instance.playersTurn)
return;
horizontal = (int)Input.GetAxisRaw ("Horizontal");
vertical = (int)Input.GetAxisRaw ("Vertical");
//dont allow vertical movement
if (horizontal != 0)
vertical = 0;
//if a key is pressed:
if (vertical != 0 || horizontal != 0)
AttemptMove<Wall> (horizontal, vertical);
}
protected override void AttemptMove <T>(int xDir, int yDir)
{
food--;
foodText.text = "Food: " + food;
base.AttemptMove<T> (xDir, yDir);
CheckIfGameOver ();
GameManager.instance.playersTurn--;
}
the GameManager.instance.playersTurn--; decrements until zero even if I have only moved once. How can I decrement it once per movement? I think the problem is that this is being called in update. Any pointers will be a great help, thanks guys.
Here is the other code from my parent class in case the error might lie here:
protected bool Move(int xDir, int yDir, out RaycastHit2D hit)
{
Vector2 start = transform.position;
Vector2 end = start + new Vector2 (xDir, yDir);
boxCollider.enabled = false;
hit = Physics2D.Linecast (start, end, blockingLayer);
boxCollider.enabled= true;
if (hit.transform == null) {
StartCoroutine (SmoothMovement (end));
return true;
}
return false;
}
protected virtual void AttemptMove<T> (int xDir, int yDir)
where T: Component
{
RaycastHit2D hit;
bool canMove= Move (xDir, yDir, out hit);
if (hit.transform == null)
return;
T hitComponent = hit.transform.GetComponent<T> ();
if (!canMove && hitComponent != null)
OnCantMove (hitComponent);
}
protected IEnumerator SmoothMovement(Vector3 end)
{
float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
while (sqrRemainingDistance > float.Epsilon) {
Vector3 newPosition = Vector3.MoveTowards (rb2d.position, end, inverseMoveTime * Time.deltaTime);
rb2d.MovePosition (newPosition);
sqrRemainingDistance = (transform.position - end).sqrMagnitude;
yield return null;
}
}

Unity does not update NavMeshAgent destination in coroutine

I'm working on an AI script in Unity 5 mostly constructed of coroutines to move around an AI object in my game. It actually works pretty well and is frame independent that way. I'm trying to avoid cluttering the Update function of the class.
However, I'm trying to create a function called wander, where the AI hangs around and randomly chooses a couple of Vector3s in the area of the waypoint and travel to each of them. After that the AI should go to the next waypoint and do the same thing into infinity basically. Collision detection and all that sort is for later parts. I want to get the navigating part fixed first.
void Start(){
agent = GetComponent<NavMeshAgent> ();
collisionRange = GetComponent<CapsuleCollider> ();
collisionRange.radius = detectionRadius;
if (waypoints.Length > 0) {
StartCoroutine (patrol ());
} else {
StartCoroutine (idle (idleTime));
}
}
IEnumerator patrol(){
agent.SetDestination(waypoints[waypointIndex].position);
Debug.Log ("Patrol started, moving to " + agent.destination);
while (agent.pathPending) {
Debug.Log ("not having path");
yield return null;
}
Debug.Log ("I have a path, distance is " + agent.remainingDistance);
while (float.Epsilon < agent.remainingDistance) {
//Debug.Log ("Moving...");
yield return null;
}
StartCoroutine (nextWaypoint ());
}
IEnumerator idle(int time){
Debug.Log ("Idleing for "+ time + " seconds");
agent.Stop ();
yield return new WaitForSeconds(time);
if(waypoints.Length > 2){
agent.Resume ();
StartCoroutine(patrol());
}
}
IEnumerator wander(){
agent.Stop ();
Debug.Log ("Going to look around here for a while.");
Vector3[] points = new Vector3[wanderPoints];
for (int i = 0; i < wanderPoints; i++) {
agent.Stop ();
Vector3 point = Random.insideUnitSphere * wanderRadius;
point.y = transform.position.y;
points [i] = point;
}
agent.ResetPath ();
agent.SetDestination(points[0]);
agent.Resume ();
Debug.Log ("point: " + points [0]);
Debug.Log ("Destination: " + agent.destination);
while (float.Epsilon < agent.remainingDistance) {
Debug.Log ("Moving...");
yield return null;
}
//StartCoroutine(patrol());
yield return null;
}
IEnumerator nextWaypoint(){
Debug.Log ("Arrived at my waypoint at " + transform.position);
if (waypointIndex < waypoints.Length -1) {
waypointIndex +=1;
} else {
waypointIndex = 0;
}
StartCoroutine(wander ());
yield return null;
}
If I swap the wander function with the idle function in nextWaypoint, everything works as expected, but this bit will never work:
agent.ResetPath ();
agent.SetDestination(points[0]);
agent.Resume ();
Debug.Log ("point: " + points [0]);
Debug.Log ("Destination: " + agent.destination);
This is a bit of test code (manually setting only 1 position to go point[0], but it never will travel to that destination. SetDestination will never get updated to the points I want to set them. I've tried calculating paths (NavMeshPath) up front and everything but the destination path will not change or reset weirdly enough. I've also had the while (float.Epsilon < agent.remainingDistance) loop in the wander function as well, but with no luck since it will remain in that loop forever since there's no path to go to.
I might be missing something here, or my logic is wrong in this case. Hopefully someone could give me a little push or maybe some extra debugging options, because I have no idea why the destination doesn't get updated in my wander function.
Consider using triggers on waypoints instead, as this will be even less taxing for the system. Below is an example that will allow you to have a variable number of waypoints easily, by getting all WayPoint type children from a parent transform. The only Coroutine that is used is for idle as you said you didn't want your Update function cluttered.
I've also exposed a couple of additional variables, including a min and max idle time, and a patrol chance, which should be set to a value less than or equal to 1, representing a percentage chance of patrolling vs idle. You can also choose a min and max number of patrol points for the agent to navigate to.
In RandomActivity you can also see that there is error handling for infinitely idle (no WayPoint children under parent). The agent will also not include the current Waypoint in it's list of points to navigate to, and will not navigate to a point already navigated to during it's current patrol (every time an element is added to m_targets, it's removed from m_availableTargets).
AgentController.cs
[RequireComponent(typeof(NavMeshAgent))]
public class AgentController : MonoBehaviour
{
[SerializeField]
private Transform m_waypointParent;
[SerializeField]
private float m_minIdle;
[SerializeField]
private float m_maxIdle;
[SerializeField]
private float m_patrolChance;
[SerializeField]
private int m_minPatrolPoints;
[SerializeField]
private int m_maxPatrolPoints;
private Waypoint[] m_waypoints;
private List<Waypoint> m_availableTargets;
private List<Waypoint> m_targets;
private Waypoint m_tempWaypoint;
private int m_currentTargetIndex;
private NavMeshAgent m_navMeshAgent;
public void Start()
{
m_waypoints = m_waypointParent.GetComponentsInChildren<Waypoint>();
m_targets = new List<Waypoint>();
m_navMeshAgent = GetComponent<NavMeshAgent>();
RandomActivity();
}
private void RandomActivity()
{
if (m_waypoints.Length == 0)
{
Debug.Log("Enemy will idle forever (no waypoints found)");
StartCoroutine(Idle(Random.Range(m_minIdle, m_maxIdle)));
return;
}
if(Random.Range(0f, 1f) <= m_patrolChance)
{
//Available waypoints
m_availableTargets = new List<Waypoint>(m_waypoints);
//Remove currentpoint
if(m_targets.Count > 0)
m_availableTargets.Remove(m_targets[m_targets.Count - 1]);
//Reset list
m_targets.Clear();
m_currentTargetIndex = -1;
//Add patrol points
for (int i = 0; i < Random.Range(m_minPatrolPoints, m_maxPatrolPoints + 1); i++)
{
m_tempWaypoint = m_availableTargets[Random.Range(0, m_availableTargets.Count)];
m_targets.Add(m_tempWaypoint);
m_availableTargets.Remove(m_tempWaypoint);
}
NextWaypoint(null);
}
else
StartCoroutine(Idle(Random.Range(m_minIdle, m_maxIdle)));
}
public void NextWaypoint(Waypoint p_waypoint)
{
//Collided with current waypoint target?
if ((m_currentTargetIndex == -1) || (p_waypoint == m_targets[m_currentTargetIndex]))
{
m_currentTargetIndex++;
if (m_currentTargetIndex == m_targets.Count)
RandomActivity();
else
{
Debug.Log("Target: " + (m_currentTargetIndex + 1) + "/" + m_targets.Count + " (" + m_targets[m_currentTargetIndex].transform.position + ")");
m_navMeshAgent.SetDestination(m_targets[m_currentTargetIndex].transform.position);
}
}
}
private IEnumerator Idle(float p_time)
{
Debug.Log("Idling for " + p_time + "s");
yield return new WaitForSeconds(p_time);
RandomActivity();
}
}
Note that for this to work, I have created a tag called Enemy so as to easily differentiate between enemies and any other tiggers in your game.
WayPoint.cs
[RequireComponent(typeof(BoxCollider))]
public class Waypoint : MonoBehaviour
{
public void OnTriggerEnter(Collider p_collider)
{
if (p_collider.tag == "Enemy")
p_collider.GetComponent<AgentController>().NextWaypoint(this);
}
}
I know this is an old post but hope this helps someone.

Categories