- Home /
Movement Conflict
I have a little problem here, well, might be big, bug I don't really know.
I have a set up for 4 axes (Up, Down, Left, Right), used for the common movement configuration (WSAD).
I can move normally using the controller.SimpleMove command ( I am using Character Controller and my own script).
Some things are happening and giving me some trouble understand why:
1) When I hold W & S the movement stops, character won't move. This is great, exactly what I wanted to be fair.
2) When I hold A & D the movement stops, character won't move. Again, what I want.
3) When I hold W & S and then press either A or D the character still won't move, this is also how I want it.
4) When I hold A & S and then press either W or S the character moves either forward or backward, this is totally out of what I want, the character must not move to any direction.
Now, the strange thing is: code is the same for all movements, save the position variable.
I don't quite get why the W & S & A/D isn't going wrong, as much as I don't understand why A & D & W/S is going wrong...
I know that W & S / A & D is the way I want because the movement has the same value, so it goes 0.
Here is what I wrote:
function Update () {
var speed = 3;
var rotateSpeed : float = 3.0;
var controller : CharacterController = GetComponent(CharacterController); //Getting the character controller
//We here handle the walking moviment, considering only the directional buttom is being pressed.
// Move forward
if (Input.GetAxis ("Up")){
var forward : Vector3 = transform.TransformDirection(Vector3.forward);
var forwardSpeed : float = speed * Input.GetAxis ("Up");
controller.SimpleMove(forward * forwardSpeed);}
// Move Backward
if (Input.GetAxis ("Down")){
var backward : Vector3 = transform.TransformDirection(Vector3.forward);
var backwardSpeed : float = speed * Input.GetAxis ("Down");
controller.SimpleMove(-backward * backwardSpeed);}
// Move Left
if (Input.GetAxis ("Left")){
var left : Vector3 = transform.TransformDirection(Vector3.right);
var leftSpeed : float = speed * Input.GetAxis ("Left");
controller.SimpleMove(-left * leftSpeed);}
// Move Right
if (Input.GetAxis ("Right")){
var right : Vector3 = transform.TransformDirection(Vector3.right);
var rightSpeed : float = speed * Input.GetAxis ("Right");
controller.SimpleMove(right * rightSpeed);}
Any ideas on how to solve the situation? I tried setting up ''if'' conditiosn mixed with && to call for a movement cancellation... No good =(
Answer by robertbu · Jul 04, 2013 at 05:03 AM
The difference in behavior is based on the order you execute your 'if' statements. Note it is recommended that you only call 'SimpleMove()' once per frame. If I understand your description, if any two keys are pressed, you want no movement. Here is an alternate implementation. Note I only call SimpleMove() once in the bottom of routine. This structure allows you to modify the 'move' Vector3 for things like jumping and gravity (or whatever), and still only make one SimpleMove() call per frame.
#pragma strict
var speed = 3.0;
var rotateSpeed : float = 45.0;
private var controller : CharacterController;
function Start() {
controller = GetComponent(CharacterController); //Getting the character controller
}
function Update () {
var up = Input.GetButton("Up");
var dn = Input.GetButton("Down");
var lt = Input.GetButton("Left");
var rt = Input.GetButton("Right");
var i = 0;
if (up) i++;
if (dn) i++;
if (lt) i++;
if (rt) i++;
var move = Vector3.zero;
if (i == 1) {
if (up)
move = transform.forward * speed;
else if (dn)
move = -transform.forward * speed;
else if (rt)
move = transform.right * speed;
else if (lt)
move = -transform.right * speed;
}
controller.SimpleMove(move);
}
Thanks, it worked, to some extent... I picked your code and made some modifications, separating the code in up/down and left/right.
It work to cancel the movement perfectly, however, it doesn't allow angular movement.
I actually wish for the character to go diagonal movement to work, I tried to set up the && condition with up/left ; up;right ; down/left ; down/right, but I think I came to fail at something.
I set up two different scripts, trying to avoid the execution order of the ''if'', apparently I was able to solve some other stuff (running happening when I don't want).
As for now, I still need to figure how to set up diagonal move, when I used the && condition, as mentioned above, the character started to move diagonally whatever I pressed one of the keys.
I am trying to make the logic more intuitive, my code was one big mess... Here are the codes I've set up now, any tip on how to set up the diagonal movement while keeping the movement cancelation part?
Walk Controller:
#pragma strict
function Start () {
var controller : CharacterController = GetComponent(CharacterController); //Getting the character controller
}
function Update () {
//Here we calculate the movement variables
var speed = 3;
var controller : CharacterController = GetComponent(CharacterController); //Getting the character controller
var forward : Vector3 = transform.TransformDirection(Vector3.forward);
var right : Vector3 = transform.TransformDirection(Vector3.right);
var up = Input.GetAxis ("Up");
var dwn = Input.GetAxis("Down");
var lft = Input.GetAxis ("Left");
var rgt = Input.GetAxis ("Right");
var i = 0;
if (up) i++;
if (dwn) i++;
if (lft) i++;
if (rgt) i++;
//Here we set the vertical movement.
if (i == 1) {
if (up)
controller.Simple$$anonymous$$ove(forward);
else if (dwn)
controller.Simple$$anonymous$$ove(-forward);
} //End of function
//Here we set the horizontal movement.
if (i == 1) {
if (rgt)
controller.Simple$$anonymous$$ove(right);
else if (lft)
controller.Simple$$anonymous$$ove(-right);
} //End of function
}//End of script
I also made a ''Run Controller'', which is basically the same code with a ''* 2'' multiplying the ''forward'' and ''right'' variables, to make movement faster.
I think it is much easier to understand now, and to work on too. Thanks for the help with this part =)
Declare 'controller' at the top of the file and initialize it in Start(). There is no reason to have a GetComponent() call inside of Update(). Look at the script I posted.
GetAxis() is used for things like Joysticks that have a positive and negative setting. For each axis you can define a positive and negative button. So if you are going to use axes, you should only have two calls and check if the return value is positive or negative. Or you can use Input.GetButton() as I did in my code.
You are making two calls to Simple$$anonymous$$ove() each frame. You only want to make one. You need to build a vector and then call Simple$$anonymous$$ove() with the vector.
Okay, thanks for the help, I took a another look at your code and made a little clean up on $$anonymous$$e, changed what you suggested.
It is mostly working for what I want, movement cancel is doing great, many thanks.
Just one last question: would it be possible to set up diagonal move with this code? I tried making the ''i'' variable use a diagonal movement if the two correct buttons are pressed (like Up and Left), but I failed a setting up the diagonal move, I think I am not allowed to call another action inside the ''if''/''else if'', like calling ''move = transform.forward;'' and ''move = transform.right;'', both combined would create the diagonal movement, or so I think. Any idea?
#pragma strict
private var controller : CharacterController;
function Start () {
controller = GetComponent(CharacterController); //Getting the character controller
}
function Update () {
//Here we calculate the movement variables
var speed = 3; //Running Speed
var up = Input.GetButton ("Up"); //$$anonymous$$ovement Button
var dwn = Input.GetButton("Down"); //$$anonymous$$ovement Button
var lft = Input.GetButton("Left"); //$$anonymous$$ovement Button
var rgt = Input.GetButton("Right"); //$$anonymous$$ovement Button
var run = Input.GetButton ("Run"); //Running Button
var i = 0;
if (up) i++;
if (dwn) i++;
if (lft) i++;
if (rgt) i++;
var move = Vector3.zero; //Our $$anonymous$$ovement Variable
//$$anonymous$$ovement Set Up For Walking
if (i == 1) {
if (up) //Forward
move = transform.forward;
else if (dwn) //Backward
move = -transform.forward;
else if (lft) //Left
move = -transform.right ;
else if (rgt) //Right
move = transform.right;
} //End of Function
//$$anonymous$$ovement Set Up For Running
if (i == 1) {
if ((up) && (run)) //Forward
move = transform.forward * speed;
else if ((dwn) && (run)) //Backward
move = -transform.forward * speed;
else if ((lft) && (run)) //Left
move = -transform.right * speed;
else if ((rgt) && (run)) //Right
move = transform.right * speed;
} //End of Function
if (i == 2) {
if ((up) && (lft)) //Diagonal
move = (transform.forward);
else if ((up) && (rgt)) //Diagonal
move = -transform.forward;
else if ((dwn) && (lft)) //Diagonal
move = -transform.right;
else if ((dwn) && (rgt)) //Diagonal
move = transform.right;
} //End of Function
//Define the Simple $$anonymous$$ove.
controller.Simple$$anonymous$$ove(move);
} //End of script
Here is how I might rewrite your script:
#pragma strict
private var runSpeed = 3.0;
private var walkSpeed = 1.0;
private var controller : CharacterController;
function Start () {
controller = GetComponent(CharacterController); //Getting the character controller
}
function Update () {
//Here we calculate the movement variables
var up = Input.GetButton ("Up"); //$$anonymous$$ovement Button
var dwn = Input.GetButton("Down"); //$$anonymous$$ovement Button
var lft = Input.GetButton("Left"); //$$anonymous$$ovement Button
var rgt = Input.GetButton("Right"); //$$anonymous$$ovement Button
if (up && dwn) return;
if (lft && rgt) return;
var move = Vector3.zero; //Our $$anonymous$$ovement Variable
if (up)
move += transform.forward;
if (dwn)
move -= transform.forward;
if (rgt)
move += transform.right;
if (lft)
move -= transform.right;
if (Input.GetButton ("Run"))
move *= runSpeed;
else
move *= walkSpeed;
controller.Simple$$anonymous$$ove(move);
} //End of script
Hum, works perfectly, I didn't knew about the ''return'' function, man, many thanks, you really solved a big mess I made, can't thank you enough... I'll sure remember you when the game is ready.
Again, thanks for the help =)
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
How do I set up my players controller script (How do I change the controls used to move and look) 2 Answers
Need Help with this movement Script 0 Answers
CharacterController unexpectedly moving up 0 Answers
What's the best alternative to Character Controller? 2 Answers