I am new to Unity and I am using the following CharacterController for my character. Everything is working well, except that sometimes the character jumps and sometimes it doesn't when I hit the spacebar. I used Debog.Log using Raycast to check if my character is grounded, and the result was True. So what is preventing my character from jumping whenever I hit the key?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class RPGMovement : MonoBehaviour
{
public float ForwardSpeed = 8f;
public float BackwardSpeed = 4f;
public float StrafeSpeed = 5f;
public float RotateSpeed = 110f;
CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
Vector3 playerVelocity;
private bool groundedPlayer;
private float jumpHeight = 0.9f;
private float gravityValue = -20.81f;
void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Animator = GetComponent<Animator>();
m_PhotonView = GetComponent<PhotonView>();
m_TransformView = GetComponent<PhotonTransformView>();
}
void Update()
{
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
void UpdateAnimation()
{
Vector3 movementVector = transform.position - m_LastPosition;
float speed = Vector3.Dot(movementVector.normalized, transform.forward);
float direction = Vector3.Dot(movementVector.normalized, transform.right);
if (Mathf.Abs(speed) < 0.2f)
{
speed = 0f;
}
if (speed > 0.6f)
{
speed = 1f;
direction = 0f;
}
if (speed >= 0f)
{
if (Mathf.Abs(direction) > 0.7f)
{
speed = 1f;
}
}
m_AnimatorSpeed = Mathf.MoveTowards(m_AnimatorSpeed, speed, Time.deltaTime * 5f);
m_Animator.SetFloat("Speed", m_AnimatorSpeed);
m_Animator.SetFloat("Direction", direction);
m_LastPosition = transform.position;
}
void ResetSpeedValues()
{
m_CurrentMovement = Vector3.zero;
m_CurrentTurnSpeed = 0;
}
void ApplySynchronizedValues()
{
m_TransformView.SetSynchronizedValues(m_CurrentMovement, m_CurrentTurnSpeed);
}
void MoveCharacterController()
{
m_CharacterController.Move(m_CurrentMovement * Time.deltaTime);
}
void UpdateForwardMovement()
{
if (Input.GetKey(KeyCode.W) || Input.GetAxisRaw("Vertical") > 0.1f)
{
m_CurrentMovement = transform.forward * ForwardSpeed;
}
}
void UpdateBackwardMovement()
{
if (Input.GetKey(KeyCode.S) || Input.GetAxisRaw("Vertical") < -0.1f)
{
m_CurrentMovement = -transform.forward * BackwardSpeed;
}
}
void UpdateStrafeMovement()
{
if (Input.GetKey(KeyCode.Q) == true)
{
m_CurrentMovement = -transform.right * StrafeSpeed;
}
if (Input.GetKey(KeyCode.E) == true)
{
m_CurrentMovement = transform.right * StrafeSpeed;
}
}
void UpdateRotateMovement()
{
if (Input.GetKey(KeyCode.A) || Input.GetAxisRaw("Horizontal") < -0.1f)
{
m_CurrentTurnSpeed = -RotateSpeed;
transform.Rotate(0.0f, -RotateSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.D) || Input.GetAxisRaw("Horizontal") > 0.1f)
{
m_CurrentTurnSpeed = RotateSpeed;
transform.Rotate(0.0f, RotateSpeed * Time.deltaTime, 0.0f);
}
}
void UpdateJump()
{
groundedPlayer = m_CharacterController.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
m_Animator.SetTrigger("Jump");
print("Jumping Now");
}
playerVelocity.y += gravityValue * Time.deltaTime;
m_CharacterController.Move(playerVelocity * Time.deltaTime);
}
}
Best guess is that "m_PhotonView.isMine" is not returning true on the frames where you're missing input. It only checks jump input for that frame, so if the last frame you pressed it but jumping wasn't checked then that input is lost forever. First test this. Change the update code to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Jump was pressed at {Time.time}"); }
if (m_PhotonView.isMine == true)
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Attempting Jump at {Time.time}"); }
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
Then play the game and jump a bunch. The first debug log line should happen every time you click the spacebar no matter what. The second debug line would only happen if physics are calculated that frame. Both have times attached. Keep jumping until the jump doesn't work. If that jump only produces the first debug log and not the second, then I am correct and that is your issue.
If so, then it's an easy fix. Add a new bool variable called "jumpInput". Whenever you check if jump was pressed, instead check if "jumpInput" is true. Then, change update to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { jumpInput = true; }
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
jumpInput = false;
}
UpdateAnimation();
}
This way if you pressed jump, it's set to true... but it's only set to false after physics are done. So if you press jump on frame 20 and physics are somehow not calculated until frame 25, it'll still know that you pressed jump at some point and thus execute it. If you're using networking, you might want to also have another variable that's what frame jump was pressed. That way you can figure out how many frames it's been since input and compensate for missed time in the jump if necessary.
Related
I'm developping a 3D game Unity with a squirrel as the player.
I'm struggling with a problem of slopes. I know, there are a bunch of tutorial to go down a slope whithout 'floating in the air while walking' but I didn't find a fine solution. I think it's because of the horizontal animations of the squirrel (maybe). I have tried with addForce, with a modified speed, with gravity... (maybe I implemented it wrong). I know I can check if I'm in the air or not with CharacterController.isGrounded but I can't force the squirrel to stick on the slope while running or walking. I'm sorry by advance if my question is too vague or simple.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class Squirrel : MonoBehaviour {
Animator squirrel;
public float gravity = 1.0f;
private Vector3 moveDirection = Vector3.zero;
float axisH, axisV;
public static int munitions = 0;
Rigidbody rb;
[SerializeField]
float walkSpeed = 2f, runSpeed = 8f, rotSpeed = 100f, jumpForce = 350;
private bool isJumpKeyDown = false;
[SerializeField] bool isJumping = false;
Animator characterAnimator;
int JumpCount = 0;
public int MaxJumps = 1; //Maximum amount of jumps (i.e. 2 for double jumps)
[SerializeField] GameObject nb_munitions;
CharacterController characterController;
// Use this for initialization
void Start () {
munitions = 0;
squirrel = GetComponent<Animator>();
rb = GetComponentInChildren<Rigidbody>();
characterAnimator = GetComponent<Animator>();
JumpCount = MaxJumps;
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
GetInput();
nb_munitions.GetComponent<Text>().text = "Glands : " + munitions; //Affichage du score
Move();
}
private void FixedUpdate()
{
if (isJumpKeyDown)
{
squirrel.SetTrigger("jump");
JumpCount -= 1;
isJumpKeyDown = false;
}
}
public void GetInput()
{
axisV = Input.GetAxis("Vertical");
axisH = Input.GetAxis("Horizontal");
}
private void Move()
{
if (characterController.isGrounded)
{
//On the ground
}
else
{
//on the air
}
if (axisV > 0)
{
if (Input.GetKeyDown(KeyCode.LeftControl))
{
transform.position += Vector3.forward * walkSpeed * Time.deltaTime;
squirrel.SetBool("walk", true);
}
else
{
transform.position += Vector3.forward * runSpeed * Time.deltaTime;
squirrel.SetFloat("run", axisV);
squirrel.SetBool("walk", false);
}
}
else
{
squirrel.SetFloat("run", 0);
}
if (axisH != 0 && axisV == 0)
{
squirrel.SetFloat("h", axisH);
}
else
{
squirrel.SetFloat("h", 0);
}
if (axisH != 0)
{
transform.Rotate(Vector3.up * rotSpeed * Time.deltaTime * axisH);
}
if (Input.GetKeyDown(KeyCode.Space))
{
if (JumpCount > 0)
{
isJumpKeyDown = true;
}
}
//Call munitions
if (Input.GetKeyDown(KeyCode.LeftShift))
{
if (Squirrel.munitions > 0)
{
SpawnerScript.Instance.NewSpawnRequest();
munitions--;
}
}
}
}
You can try to get the angle of the slope and make it the pitch for the mesh of the squirrel.
I finally found the problem. My C# script "overwrited" the CharacterController and did not allow the squirrel to go down the slopes. Make sure you follow a move script that "respects" the CharacterController (if you pick one or you'll be fighting windmills).
I'm really new to Unity 3d and I'm trying to make a respawn with my character. It seems that the answer is really easy but I cannot see why my code is not working. If this is a duplicate, let me know.
public Vector3 PointSpawn;
void Start()
{
PointSpawn = gameObject.transform.position;
}
void Update()
{
if (gameObject.transform.position.y < 10)
{
gameObject.transform.position = PointSpawn; // This doesn't work
// gameObject.transform.LookAt(PointSpawn); ---> This DOES work ok
}
}
Parallel Script
public float HorizontalMove;
public float VerticalMove;
private Vector3 playerInput;
public CharacterController player;
public float MoveSpeed;
private Vector3 movePlayer;
public float gravity = 9.8f;
public float fallVelocity;
public float JumpForce;
public bool DoubleJump = false;
public Camera mainCamera;
private Vector3 camForward;
private Vector3 camRight;
void Start()
{
player = GetComponent<CharacterController>();
}
void Update()
{
HorizontalMove = Input.GetAxis("Horizontal");
VerticalMove = Input.GetAxis("Vertical");
playerInput = new Vector3(HorizontalMove, 0, VerticalMove);
playerInput = Vector3.ClampMagnitude(playerInput, 1);
CamDirection();
movePlayer = playerInput.x * camRight + playerInput.z * camForward;
movePlayer = movePlayer * MoveSpeed;
player.transform.LookAt(player.transform.position + movePlayer);
setGravity();
PlayerSkills();
player.Move(movePlayer * Time.deltaTime );
}
void CamDirection()
{
camForward = mainCamera.transform.forward;
camRight = mainCamera.transform.right;
camForward.y = 0;
camRight.y = 0;
camForward = camForward.normalized;
camRight = camRight.normalized;
}
void PlayerSkills()
{
if (player.isGrounded && Input.GetButtonDown("Jump"))
{
fallVelocity = JumpForce;
movePlayer.y = fallVelocity;
DoubleJump = true;
}
else if (player.isGrounded == false && Input.GetButtonDown("Jump") && DoubleJump == true)
{
fallVelocity = JumpForce *2;
movePlayer.y = fallVelocity;
DoubleJump = false;
}
}
void setGravity()
{
if (player.isGrounded)
{
fallVelocity = -gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
else
{
fallVelocity -= gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
}
Thanks in advance!
Just so the answer to the question is not in the comments:
The original problem is that the assignment gameObject.transform.position = PointSpawn appeared to do nothing. As the line is written properly, the position of this gameObject, must have been getting overwritten elsewhere.
With the addition of OP's movement script, the position of the player was getting overwritten in the movement's Update function. As the other assignment was being done in Update, the call order was not guaranteed to work as intended. The fix is either to assure that the movement Update is run not the frame of the new position assignment or to move the conditional and the assignment to a function that always runs after Update regardless of script execution order, LateUpdate.
I would like to ask if there is a way to disable diagonal movement in Unity 2D.
The thing is when I press 'W' + 'D'(move key) at the same time then the character starts to move diagonally.
So instead of the character moving diagonal when combining button press, I want it to go completely straight instead if I press 'd' or any other key to move even if I'm still pressing the other button at the same time. So to say prioritize the function of the last button I pressed.
Here's a short video to explain my problem further .
https://youtu.be/aPZii5HfP4s
And here's the code for my character movement.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class keycontrol : MonoBehaviour
{
public float moveSpeed = 0f;
public Rigidbody2D rb2d;
Vector2 movement;
public Animator animator;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
void FixedUpdate()
{
rb2d.MovePosition(rb2d.position + movement * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 200 * Time.deltaTime;
animator.speed = 1.5f;
}
else
{
moveSpeed = 110 * Time.deltaTime;
animator.speed = 1f;
}
}
}
Thanks for help
A simple way to do this is to prioritize one axis over the other and just wrap the other check in a condition.
movement.x = Input.GetAxisRaw("Horizontal");
if (movement.x != 0)
{
movement.y = Input.GetAxisRaw("Vertical");
}
However, this can fail, because depending on your input, the axis might return values close to zero when using a controller. In this case, you could just get both values and check for the larger one.
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
if (Mathf.Abs(movement.x) > Mathf.Abs(movement.y))
{
movement.y = 0;
}
else
{
movement.x = 0;
}
Sharing as an answer since I can't comment on this post, you should check out the new input system unity released recently: https://docs.unity3d.com/Packages/com.unity.inputsystem#1.0/manual/QuickStartGuide.html
It gives better control over inputs such as event systems so you can lock the movement until the first key is released.
You can handle the movement only in one of the axis handled each chance in the code, find draft below:
bool isXMoving;
bool isYMoving;
// Update is called once per frame
void Update()
{
if (Input.GetAxisRaw("Horizontal") != 0f && !isYMoving) {
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = 0;
isXMoving = true;
isYMoving = false;
}
if (Input.GetAxisRaw("Horizontal") != 0f && !isXMoving) {
movement.y = Input.GetAxisRaw("Vertical");
movement.x = 0;
isYMoving = true;
isXMoving = false;
}
Debug.Log($"X: {movement.x} Y: {movement.y}"); //check
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
You can add condition to check if the horizontal movement is pressed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class keycontrol : MonoBehaviour
{
public float moveSpeed = 0f;
public Rigidbody2D rb2d;
Vector2 movement;
public Animator animator;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
if(movement.x == 0){
movement.y = Input.GetAxisRaw("Vertical");
}
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
void FixedUpdate()
{
rb2d.MovePosition(rb2d.position + movement * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 200 * Time.deltaTime;
animator.speed = 1.5f;
}
else
{
moveSpeed = 110 * Time.deltaTime;
animator.speed = 1f;
}
}
}
So I was trying to implement double jumping in my game, which doesn't work. And now, somehow, not only can't my players double jump, they can't even jump either!
update: they can jump now, still can't double jump though.
This is my whole movement script:
using UnityEngine;
namespace Players
{
public class Actor : MonoBehaviour
{
//in order to control both players using 1 script.
public int playerIdx;
//Variables.
public float movementSpeed = 150f;
public float jumpForce = 250f;
//Ground stuff.
public LayerMask whatIsGround;
public bool grounded;
//boolean stuff.
private bool facingRight;
private bool moving;
//Needed to check if player is on the ground.
public Transform groundCheck;
//Limit player's movement speed.
public float maxMovementSpeed = 400f;
//Double jump stuff.
private bool doubleJumpReady;
//rb
private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
doubleJumpReady = true;
rb = GetComponent<Rigidbody2D>();
facingRight = true;
}
// Update is called once per frame
void FixedUpdate()
{
SlowDown();
}
private void LateUpdate()
{
grounded = Physics2D.OverlapCircle(groundCheck.position, 0.1f, whatIsGround);
if (grounded)
doubleJumpReady = true;
}
private void SlowDown()
{
if (moving) return;
//if player is not moving, slow them down.
if (rb.velocity.x > 0.2f)
rb.AddForce(movementSpeed * Time.deltaTime * -Vector2.right);
if (rb.velocity.x < -0.2f)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right);
}
public void Move(int dir)
{
//Flip the player.
Flip(dir);
//Moving the player.
moving = true;
float xVel = rb.velocity.x; //Get x velocity.
if ( dir > 0)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right * dir);
else if (dir < 0)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right * dir);
else if (dir == 0) { } //do nothing.
//Help player turn around faster.
if (xVel > 0.2f && dir < 0)
rb.AddForce(movementSpeed * 3.2f * Time.deltaTime * -Vector2.right);
if (xVel < 0.2f && dir > 0)
rb.AddForce(movementSpeed * 3.2f * Time.deltaTime * Vector2.right);
}
private void Flip(int dir)
{
if (facingRight && dir == -1 || !facingRight && dir == 1)
{
facingRight = !facingRight;
transform.Rotate(0f, 180f, 0f);
}
}
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
grounded = false;
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
}
}
}
}
I don't know if it is because of my jump script, or my player script:
void Update()
{
if (playerIdx == 1)
{
if (Input.GetKey(KeyCode.A))
Move(-1);
if (Input.GetKey(KeyCode.D))
Move(1);
if (Input.GetKey(KeyCode.W))
Jump();
}
if (playerIdx == 2)
{
if (Input.GetKey(KeyCode.LeftArrow))
Move(-1);
if (Input.GetKey(KeyCode.RightArrow))
Move(1);
if (Input.GetKey(KeyCode.UpArrow))
Jump();
}
}
So how can I fix this?
as far as i can see you never reset the
doubleJumpReady = false;
Variable. To fix this simply change the jump code to:
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
grounded = false;
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
}
}
Hope it works ;).
EDIT:
grounded is set by overlapping spheres. Therefore no need to set it here.
Use this code and press your jump btn 2 times and see if the Debug.Log message shows up. Also, your player ID (idx is not needed.) As far as i can see your script is attached two to different objects. Therefore their variables are not shared anyways.
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
Debug.Log("I am double jumping");
}
}
And the final problem is, you do not execute one of your jumps you execute both at once.
THis happens due to your execution.
Input.GetKey(KeyCode.UP)
instead use:
Input.GetKeyDown(KeyCode.Up);
GetKeyDown returns true when the button is pressed.
GetKey returns true WHILE the button is pressed.
Hope it works now ;)
I would implement it with a counter, you can set the number of jumps you want.
The code would be like this:
jumpCount = 0;
protected void Jump()
{
if(!grounded && jumpCount < 2)
{
jumpCount++;
rb.AddForce(Vector2.up * jumpForce);
}
if(grounded)
jumpCount = 0;
}
Going off the assumption that you can now perform the normal jump again after reading the comments. I think the reason you can't 'double jump' is that when you call the Jump() method, you don't just call it once, you call it twice, so what happens is the player jumps and then immediately double jumps and so you don't actually notice that the double jump has occurred. You could make it so that your doubleJumpReady boolean is only true after a set amount of time after you have jumped initially using some sort of co-routine or something I implemented for a sort of double jump mechanic once was that the user could press the jump button again to double jump only when the player had reached the maximum height of the initial jump or after.
so I'm working on a project in Unity3D and I'm having the following issue:
When I initially start the game, the character is not moving, which is intended. Then, when I hit "W" to move, my character starts moving and animates. However, when I let off the key, she doesn't stop moving forward.
Even if I hit the "S" key to move backward, after I let up, she starts moving forward again while no keys are pressed, and for the life of me I can't figure out why.
Here's the script I'm using on her if that helps:
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour
{
private CharacterController controller;
public float speed = 20.0f;
private Vector3 moveDirection = Vector3.zero;
public float gravity = 20.0f;
private bool winState = false;
private bool loseState = false;
private bool isBlocking = false;
private Animator anim;
// Use this for initialization
void Start ()
{
controller = this.GetComponent<CharacterController>();
anim = GetComponent<Animator>();
anim.SetBool("Ready_Bool", true);
}
// Update is called once per frame
void FixedUpdate ()
{
//GameObject center = GameObject.Find("MiddleOfRing");
GameObject opponent = GameObject.Find("Opponent");
checkAnimations();
float turn = Input.GetAxis("Horizontal");
//print("Horizontal: " + turn);
if(turn < 0)
moveLeft();
else if(turn > 0)
moveRight();
float vertDirection = Input.GetAxis("Vertical");
//print ("Vertical: " + vertDirection);
print ("Controller Velocity: " + controller.velocity.magnitude); //for testing
if(controller.isGrounded)
{
moveDirection = transform.forward * vertDirection * speed;
anim.SetFloat("Speed", controller.velocity.magnitude);
}
if(vertDirection > 0)
moveForward(moveDirection);
else if(vertDirection < 0)
moveBackward(moveDirection);
else
controller.Move(moveDirection * Time.deltaTime);
moveDirection.y = moveDirection.y - gravity * Time.deltaTime;
transform.LookAt(opponent.transform.position);
opponent.transform.LookAt(this.transform.position);
}
void moveLeft()
{
GameObject opponent = GameObject.Find("Opponent");
transform.RotateAround(opponent.gameObject.transform.position, Vector3.up, speed/2 * Time.deltaTime);
//for testing purposes, to be replaced with actual AI
opponent.transform.RotateAround(transform.position, Vector3.up, speed/2 * Time.deltaTime);
//tells Animator character is moving left
anim.SetBool("MoveLeft_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveRight()
{
GameObject opponent = GameObject.Find("Opponent");
transform.RotateAround(opponent.gameObject.transform.position, Vector3.down, speed/2 * Time.deltaTime);
//for testing purposes, to be replaced with actual AI
opponent.transform.RotateAround(transform.position, Vector3.down, speed/2 * Time.deltaTime);
//tells Animator character is moving right
anim.SetBool("MoveRight_Bool", true);
anim.SetBool("MoveLeft_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveForward(Vector3 move)
{
GameObject opponent = GameObject.Find("Opponent");
float distance = Vector3.Distance(this.transform.position, opponent.transform.position);
//keeps characters at a certain distance from each other
if(distance >= 3)
{
controller.Move(move * Time.deltaTime);
}
//tells Animator character is moving forward
anim.SetBool("MoveForward_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveLeft_Bool", false);
anim.SetBool("MoveBackward_Bool", false);
}
void moveBackward(Vector3 move)
{
GameObject opponent = GameObject.Find("Opponent");
moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
controller.Move(move * Time.deltaTime);
//tells Animator character is moving backward
anim.SetBool("MoveBackward_Bool", true);
anim.SetBool("MoveRight_Bool", false);
anim.SetBool("MoveForward_Bool", false);
anim.SetBool("MoveLeft_Bool", false);
}
void checkAnimations()
{
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if(Input.GetKeyDown(KeyCode.E))
{
anim.SetTrigger("JabR_Trig");
checkHit();
isBlocking = false;
}
else if(Input.GetKeyDown(KeyCode.Q))
{
anim.SetTrigger("JabL_Trig");
checkHit();
isBlocking = false;
}
else if(Input.GetKey(KeyCode.B))
{
anim.SetTrigger("Block_Trig");
isBlocking = true;
}
else
{
isBlocking = false;
}
}
void checkHit()
{
GameObject opponent = GameObject.Find("Opponent");
float distance = Vector3.Distance(this.transform.position, opponent.transform.position);
if(distance <= 4.0f)
{
}
}
public bool getBlocking()
{
return isBlocking;
}
}
I think the problem may be that I'm using controller.velocity.magnitude incorrectly.
If anyone can help me out, I would appreciate it!
this line:
moveDirection = transform.forward * vertDirection * speed;
should be this:
moveDirection = transform.forward * vertDirection * speed * Time.deltaTime;
this else block:
else
controller.Move(moveDirection * Time.deltaTime);
should look like this:
else
controller.Move(Vector3.zero);
I actually figured it out. My animator didn't have one of the transitions set up, so the character was stuck in an animation.
Thanks!