I’m using camera-relative movement (been testing with with camera rotation at X20 Y30) and doing the “is grounded” update through OnCollisionEnter and OnCollisionExit when interacting with rigidbodies tagged as “Floor”.
But for some reason when the character is moving NE (moving at negative distance at both X and Z) it will occasionally skip the Jump trigger even though the isGrounded is set true.
I decided to call for help because i wasn’t able to figure out the reason it’s happening seeing Move () and Jump () aren’t sharing data for one to be affecting other. Here the code (posting it all since it may or may not have to do with the character XZ movement):
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : MonoBehaviour
{
public float MoveSpeed = 6f;
public float TurnSpeed = 360f;
public float JumpSpeed = 2f;
private Transform cam;
private Vector3 camMove;
private Vector3 movement;
private float turnAmount;
public bool isGrounded;
Rigidbody playerRigidbody;
void Awake () {
playerRigidbody = GetComponent <Rigidbody> ();
cam = Camera.main.transform;
}
void FixedUpdate () {
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
camMove = v * cam.forward + h * cam.right;
Move (camMove);
Jump ();
}
void Move (Vector3 move) {
move = transform.InverseTransformDirection (move);
if (move != Vector3.zero) {
turnAmount = Mathf.Atan2 (move.x, move.z);
transform.Rotate (0, turnAmount * TurnSpeed * Time.deltaTime, 0);
}
movement.Set (camMove.x, 0f, camMove.z);
movement = movement.normalized * MoveSpeed * Time.deltaTime;
playerRigidbody.MovePosition (playerRigidbody.position + movement);
}
void Jump () {
if (Input.GetKeyDown (KeyCode.Space) && isGrounded == true) {
playerRigidbody.AddForce (Vector3.up * JumpSpeed);
}
}
void OnCollisionEnter (Collision col) {
if (col.gameObject.tag == "Floor") {
isGrounded = true;
}
}
void OnCollisionExit (Collision col) {
if (col.gameObject.tag == "Floor") {
isGrounded = false;
}
}
}
At start i was using a raytrace-based grounded detection (Physics.Raytrace (ray, groundDistance, floorMask)) in a similar way to standard asset’s thirdPersonController but was having similar issue (and a few others too) so i changed to a collision-based detection. The change fixed all other issues but this one that is causing jump trigger to be skipped.
Thanks.
EDIT: Adding camera script for those willing to try it out and see if the bug happens.
using UnityEngine;
using System.Collections;
public class CameraMovement : MonoBehaviour {
public float spin = 5f;
public float startingCamX = 20f;
public float startingCamY = 45f;
private Quaternion handler;
private Transform cam;
void Awake () {
cam = Camera.main.transform;
transform.rotation = Quaternion.Euler (startingCamX, startingCamY, 0);
}
void FixedUpdate () {
cam.transform.LookAt (transform.position);
float currentCamX = startingCamX;
float currentCamY = startingCamY;
if (Input.GetKeyDown (KeyCode.Keypad4)) {
startingCamY += 15f;
} else if (Input.GetKeyDown (KeyCode.Keypad6)) {
startingCamY -= 15f;
} else if (Input.GetKeyDown (KeyCode.Keypad8)) {
if (startingCamX < 60) {
startingCamX += 10f;
}
} else if (Input.GetKeyDown (KeyCode.Keypad2)) {
if (startingCamX > 0) {
startingCamX -= 10f;
}
}
transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler (startingCamX, startingCamY, 0), spin * Time.deltaTime);
}
}
This script is for an empty created at same spot as the character’s empty and has the main camera as child so it can use the empty as pivot and orbit around the character. I use the camera ortographic with distance with starting position (0, 0, -90) while the character and pivot are at (0, 0, 0).
The follow script at camera empty is:
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Transform target;
public float smoothing = 5f;
Vector3 offset;
void Start ()
{
offset = transform.position - target.position;
}
void FixedUpdate ()
{
Vector3 targetCamPos = target.position + offset;
transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
}
}
Hopefully they’re enough for one to try it, experience the bug and hopefully figure out what’s causing it.