- Home /
Roll/Dodge/Evade System
I am trying to make my character be able to evade attacks. My movement script is quite long but this is the portion of code I am using.
if(evading)
{
moveDirection = playerRotation.transform.forward / 5 * evadeSpeed;
moveSpeed = evadeSpeed;
}
The problem here is that I don't have control over the two things I need:
The distance of the roll and the speed in which the character covers the distance. I am uncertain how to control these.
@HappyMoo's comment : The evasion occurs in the forward direction because the forward direction is the direction the character is facing, that's the style I want for my game.
void ProcessEvasionTime()
{
//evasion timer for action performed
if(evading)
{
evadeTimer -= Time.deltaTime;
if(evadeTimer <= 0)
{
anim.SetBool("Evading", false);
evading = false;
cooldownInEffect = true;
}
}else
{
evadeTimer = evadeTime;
}
if(!evading && InputManager.ActiveDevice.GetControl(InputControlType.Action1))
{
ProcessEvasion();
}
if(cooldownInEffect)
{
cooldownTimer -= Time.deltaTime;
if(cooldownTimer <= 0)
{
cooldownInEffect = false;
cooldownTimer = cooldown;
}
}
}
void ProcessEvasion()
{
if(!cooldownInEffect)
{
//timers
evading = true;
evadeTimer = evadeTime;
//move character to evade and set animator to play evasion animation
anim.SetBool("Evading", true);
}
}
Character Movement: Note - The input system is a custom script to allow cross controller support, just think of it as input.getaxis or relevant alternative.
void Update()
{
InputManager.Update();
//cache the inputs
//h = Input.GetAxis ("Horizontal");
h = InputManager.ActiveDevice.GetControl(InputControlType.LeftStickX);
//v = Input.GetAxis ("Vertical");
v = InputManager.ActiveDevice.GetControl(InputControlType.LeftStickY);
//s = Input.GetAxis ("Strafe");
//mh = Input.GetAxis ("Mouse X");
//zero the move direction so previous data is removed
moveDirection = Vector3.zero;
//check if it's grounded, otherwise player cannot move, also check for the deadzone
if(characterController.isGrounded)
{
if (v > deadZone || v < -deadZone)
{
moveDirection = new Vector3 (0f, 0f, v);
}
//add horizontal movement to the (currently)vertical movement vector
moveDirection.x = h;
//process turning
//ProcessTurning(s, mh);
//normalize the diagonal inputs to prevent values above 1
if (moveDirection.magnitude > 1)
{
moveDirection.Normalize ();
}
//move character in the direction of the camera's facing angle
moveDirection = cam.transform.TransformDirection(moveDirection);
}
//change movement speed if weapon unsheathed
if(anim.GetBool("Unsheathed") == true && !evading)
moveSpeed = walkSpeed;
else
moveSpeed = runSpeed;
//process evasion timers
if(combo!= null && combo.attackTimer <= 0)
ProcessEvasionTime();
//all events for when the player loses control of character eg. talking, cutscene, death, evading
RevokeControl();
//set the animator's Speed float to the magnitude of the moveDirection to allow for the run animation to play
anim.SetFloat ("Speed", moveDirection.magnitude);
//calculate gravity
moveDirection.y = -gravity * Time.deltaTime;
//move the character
characterController.Move (moveDirection * moveSpeed * Time.deltaTime);
transform.Rotate(turnDirection * Time.deltaTime);
//control player facing direction when strafing, moving backward, etc
if(moveDirection.x > deadZone || moveDirection.x < -deadZone || moveDirection.z > deadZone || moveDirection.z < -deadZone)
{
desiredRotation = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
playerRotation.transform.rotation = Quaternion.RotateTowards(playerRotation.transform.rotation, desiredRotation, rotateSpeed * 10 * Time.deltaTime);
}
}
You're evading in forward direction? evading sounds more like sideways - can you explain?
Alos, how is your controlling scheme? Can you add the code that turns evading on and the one that turns it off again.
I edited the primary post with the information, and commented on the forward direction but suppose that bit belonged here :) He evades in the direction he faces.
The distance of the roll and the speed in which the character covers the distance... Do you mean that the player should be able to control these or are you just trying sync with your roll animation so it looks good? If the second, can you add your code which actually moves the character?
Also, are you aware that SetTrigger exists? so you can only trigger an animation and let it run out without having to manually set to false again from outside.
Thanks for the SetTrigger tip.. will have to update my code. It's not about syncing the animation. The player can not control those. I want to define how far he rolls, and how fast he gets to the end of the roll destination.
That shouldn't be that hard. Let me know when you updated the code above an I'll have a look
Answer by HappyMoo · Jan 17, 2014 at 04:30 PM
Things I noticed:
You calculate gravity in a wrong way. The way you do it, falling speed will not build up, but you always fall with the same constant velocity. And you also apply it if the player is grounded which probably means your players scrapes along the ground and you lose speed.
Strange constant 10 where rotateSpeed is used. If you don't use rotateSpeed for two different rotations and one should be 10 times faster than the other, you should include the 10 in the constant rotateSpeed.
Is it by design or by accident, that you treat deadzone differently for the different axes? In forward direction the character doesn't even react if below deadzone, but sideways you can slowly strafe, but you only turn when >deadzone
Now to ProcessEvasionTime: The cooldown timer logic is smeared over so many lines, I would pull it together. Also, do you really need cooldownTimer and cooldownInEffect? Just keep cooldownTimer at 0 and if you set it to anything elsem you're in cooldown and it counts down.
Rename ProcessEvasionTime to ProcessEvasion as it now not only processes the Timer and do this:
public float evadeTime; // this tells us how long the evade takes
public float evadeDistance; // this tells us how far player will evade
void ProcessEvasion()
{
cooldownTimer = Mathf.Max(0f, cooldownTimer - Time.deltaTime);
if(!evading && cooldownTimer==0 && InputManager.ActiveDevice.GetControl(InputControlType.Action1))
{
evading = true;
evadeTimer = evadeTime;
anim.SetTrigger("Evading");
}
if(evading)
{
evadeTimer = Mathf.Max(0f, evadeTimer - Time.deltaTime);
// Evasion overrides speed and direction
moveDirection = playerRotation.transform.forward; // evasion = full speed forward
moveSpeed = evadeDistance/evadeTime;
if(evadeTimer == 0)
{
//anim.SetBool("Evading", false);
evading = false;
}
}
}
How goes the dodging? I have a similar mechanic in my game and wanted to see how your end was going. Thanks for sharing! this has been VERY informative. However, how did you set this evasion command to a key? like press up or down or fire1.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
question with character controller to move with hitting mousebuttton down 1 Answer
Player Diagonal Velocity 1 Answer