What you would have to do is store the previous direction you moved in. I’m not quite sure how your action numbers correspond to the vectors they represent, so I’m gonna use your example at the bottom.
You will need a previousDirection
variable. If every action corresponds to a direction, this can just be an int for the last action you took. Then, when you move again, you check if it is a different move from the last direction you took. To use your example from before, and extend it with this:
Current: | (1)Up | (2)Up | (3)Up
Previous:| (1)---- | (2)Up | (3)Up
Changed:| (1)No | (2)No | (3)No [No Events]
Current: | (1)Up | (2)Right | (3)Up
Previous:| (1)---- | (2) Up | (3)Right
Changed:| (1)No | (2)YES | (3)YES [Events on 2 and 3]
Doing this in your existing code might be cumbersome, since you have so many if statements. If you’re learning C#, I would make a huge suggestion and say to avoid long if-else chains as much as possible. In your case, it’s not required, and can be greatly simplified with an array like this (your old code, no events):
//Up at the top
Vector3[] directions = {
new Vector3(0f,0f,1f),
new Vector3(-1f,0f,0f),
new Vector3(0f,0f,-1f),
new Vector3(1f,0f,0f),
new Vector3(0f,1f,0f),
new Vector3(0f,-1f,0f)
};
//Where your big chain of if-else statements was:
rBody.MovePosition(transform.position+directions[action]*0.1f);
A few things to note here are that I changed this.transform.position
to just transform.position
, since the this
is unnecessary. (If it is necessary and you named a variable ‘transform’, rename that variable. It will just make your code confusing down the line.) I also made the array contain vectors of length 1 instead of 0.1, then multiplied by 0.1 later. This makes it easier to change that scale, say if you wanted to change the movement speed. Finally, and most obviously, the array never needs changing and every action corresponds to an entry in the array. this means that any changes to the actual movement code only need to be done once rather than 6 times, reducing the potential for error.
Now, to combine the two fixes:
This is the simplified code above, but with an event that is called when the direction changes:
//In your usings, if you want to use a UnityEvent
using UnityEngine.Events;
//Up at the top
Vector3[] directions = {
new Vector3(0f,0f,1f),
new Vector3(-1f,0f,0f),
new Vector3(0f,0f,-1f),
new Vector3(1f,0f,0f),
new Vector3(0f,1f,0f),
new Vector3(0f,-1f,0f)
};
public UnityEvent OnChangeDirection; //I like UnityEvents, but this might be different if you are doing it some other way.
private int previousAction = -1; //The previous action variable discussed above
//Where your big chain of if-else statements was:
if(action != previousAction && previousAction != -1){
//The -1 part is to prevent it from firing the event when it first
// starts moving. If you want it to fire then too, just remove the
// previousAction != -1 part.
OnChangeDirection.Invoke(); //Actually calls the event
}
rBody.MovePosition(transform.position+directions[action]*0.1f);
previousAction = action; //After the action is performed, make it the previous action