- Home /
Other
AddForce Jump Problem
Hi there! I am new to Unity, and I have the following script to control my character, but I am having a problem making him jump. He plays the animation when I click space, but not actually gaining any height. There are no errors in the console. Any help is appreciated.
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;
public float JumpForce = 500f;
public Rigidbody m_rigidbody;
CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Animator = GetComponent<Animator>();
m_rigidbody = GetComponent<Rigidbody>();
m_PhotonView = GetComponent<PhotonView>();
m_TransformView = GetComponent<PhotonTransformView>();
}
void Update()
{
if( m_PhotonView.isMine == true )
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
UpdateJump();
MoveCharacterController();
ApplyGravityToCharacterController();
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 ApplyGravityToCharacterController()
{
m_CharacterController.Move( transform.up * Time.deltaTime * -9.81f );
}
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()
{
if (Input.GetKeyDown(KeyCode.Space))
{
m_rigidbody.AddForce(Vector3.up * JumpForce);
m_Animator.SetTrigger("Jump");
}
}
}
Answer by Xrank · Sep 23, 2020 at 08:50 PM
@President I'm not completely sure but I think it is because you have "Input.GetKeyDown" so it checks to see if the key was just pressed. Maybe try using "GetKey" Instead and have a timer countdown to see if you should start to fall. public float jumpTime; float currentJumpTime; void Start() { currentJumpTime = JumpTime; } void UpdateJump() { if(Input.GetKey(KeyCode.Space) && currentJumpTime <= 0) { //addForce //set trigger currentJumpTime = JumpTime; } else { currentJumpTime-= Time.deltaTime; } } Hopefully this helps!
Doesn't work. After reading about it, a character has either to have a rigidbody or a charactercontroller, but not both together.
Answer by unity_ek98vnTRplGj8Q · Sep 23, 2020 at 10:06 PM
Don't use AddForce, use CharacterController.Move instead. If you have a CharacterController, you shouldn't have a rigidbody at all. Instead, just keep track of what your vertical velocity should be each frame and add that to a CharacterController.Move call.
I am not sure how to do that. Can you please give me the exact code?! I am still learning (:
Answer by President · Sep 24, 2020 at 07:39 AM
I have updated my code and this one works, except now I have one problem. When I click "Space" key, it sometimes jumps and sometimes it doesn't. What might be the issue? 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;
private CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
private Vector3 playerVelocity;
private bool groundedPlayer;
private float jumpHeight = 0.9f;
private float gravityValue = -20.81f;
void Start()
{
m_CharacterController = gameObject.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();
UpdateJump();
MoveCharacterController();
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;
}
// Changes the height position of the player..
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
m_Animator.SetTrigger("Jump");
}
playerVelocity.y += gravityValue * Time.deltaTime;
m_CharacterController.Move(playerVelocity * Time.deltaTime);
}
}
I've had some problems personally with CharacterController.isGrounded working correctly with an animated player. $$anonymous$$y solution has always been to implement my own isGrounded by making a small trigger collider at the players feet then setting isGrounded to true OnTriggerEnter and isGrounded to false OnTriggerExit. Just make sure that it is only detecting collisions with object that you want to be able to stand on by setting your layers correctly.
Follow this Question
Related Questions
Rigidbody AddForce Up - different value. 1 Answer
jump on collision weird behaviour 2 Answers
Jump off the edge of the object 1 Answer
Making a player jump, getting random results 2 Answers
What's wrong with this script? 4 Answers