Let me just preface my question by saying I'm quite new to unity and programming as a whole. However I've been experimenting with some movement and after adding my falling function I've run into some trouble. Sometimes if I press play in Unity the character will start jittering quite heavy, every frame it also jumps between isInAir and isGrounded (as well as isInteracting). This causes my player to shake heavily and jitter forward as well.
Sometimes the falling animation will happen but my character falls really slowly, sometimes the animation doesn't work. Does anyone know how I can fix this?
Here is my PlayerLocomotion, the everything falling related is mentioned under HandleFalling.
using System.Collections.Generic;
using UnityEngine;
namespace FS
{
public class PlayerLocomotion : MonoBehaviour
{
PlayerManager playerManager;
Transform cameraObject;
InputHandler inputHandler;
public Vector3 moveDirection;
[HideInInspector]
public Transform myTransform;
[HideInInspector]
public AnimatorHandler animatorHandler;
public new Rigidbody rigidbody;
public GameObject normalCamera;
[Header("Ground & Air Detection Stats")]
[SerializeField]
float groundDetectionRayStartPoint = 0.5f;
[SerializeField]
float minimumDistanceNeededToBeginFall = 1f;
[SerializeField]
float groundDirectionRayDistance = 0.2f;
LayerMask ignoreForGroundCheck;
public float inAirTimer;
[Header("Movement Stats")]
[SerializeField]
float movementSpeed = 5;
[SerializeField]
float sprintSpeed = 7;
[SerializeField]
float rotationSpeed = 10;
[SerializeField]
float fallingSpeed = 45;
void Start()
{
playerManager = GetComponent<PlayerManager>();
rigidbody = GetComponent<Rigidbody>();
inputHandler = GetComponent<InputHandler>();
animatorHandler = GetComponentInChildren<AnimatorHandler>();
cameraObject = Camera.main.transform;
myTransform = transform;
animatorHandler.Initialize();
playerManager.isGrounded = true;
ignoreForGroundCheck = ~(1 << 10);
}
#region Movement
Vector3 normalVector;
Vector3 targetPosition;
private void HandleRotation(float delta)
{
Vector3 targetDir = Vector3.zero;
float moveOverride = inputHandler.moveAmount;
targetDir = cameraObject.forward * inputHandler.vertical;
targetDir += cameraObject.right * inputHandler.horizontal;
targetDir.Normalize();
targetDir.y = 0;
if (targetDir == Vector3.zero) targetDir = myTransform.forward;
float rs = rotationSpeed;
Quaternion tr = Quaternion.LookRotation(targetDir);
Quaternion targetRotation =
Quaternion.Slerp(myTransform.rotation, tr, rs * delta);
myTransform.rotation = targetRotation;
}
public void HandleMovement(float delta)
{
if (inputHandler.rollFlag) return;
if (playerManager.isInteracting) return;
moveDirection = cameraObject.forward * inputHandler.vertical;
moveDirection += cameraObject.right * inputHandler.horizontal;
moveDirection.Normalize();
moveDirection.y = 0;
float speed = movementSpeed;
if (inputHandler.sprintFlag)
{
speed = sprintSpeed;
playerManager.isSprinting = true;
moveDirection *= speed;
}
else
{
moveDirection *= speed;
}
Vector3 projectedVelocity =
Vector3.ProjectOnPlane(moveDirection, normalVector);
rigidbody.velocity = projectedVelocity;
animatorHandler
.UpdateAnimatorValues(inputHandler.moveAmount,
0,
playerManager.isSprinting);
if (animatorHandler.canRotate)
{
HandleRotation (delta);
}
}
public void HandleRollingAndSprinting(float delta)
{
if (animatorHandler.anim.GetBool("isInteracting")) return;
if (inputHandler.rollFlag)
{
moveDirection = cameraObject.forward * inputHandler.vertical;
moveDirection += cameraObject.right * inputHandler.horizontal;
if (inputHandler.moveAmount > 0)
{
animatorHandler.PlayTargetAnimation("Rolling", true);
moveDirection.y = 0;
Quaternion rollRotation =
Quaternion.LookRotation(moveDirection);
myTransform.rotation = rollRotation;
}
else
{
animatorHandler.PlayTargetAnimation("Backstep", true);
}
}
}
public void HandleFalling(float delta, Vector3 moveDirection)
{
playerManager.isGrounded = false;
RaycastHit hit;
Vector3 origin = myTransform.position;
origin.y += groundDetectionRayStartPoint;
if (Physics.Raycast(origin, myTransform.forward, out hit, 0.4f))
{
moveDirection = Vector3.zero;
}
if (playerManager.isInAir)
{
rigidbody.AddForce(-Vector3.up * fallingSpeed);
rigidbody.AddForce(moveDirection * fallingSpeed / 5f);
}
Vector3 dir = -moveDirection;
dir.Normalize();
origin = origin + dir * groundDirectionRayDistance;
targetPosition = myTransform.position;
Debug
.DrawRay(origin,
-Vector3.up * minimumDistanceNeededToBeginFall,
Color.red,
0.1f,
false);
if (Physics.Raycast(origin, -Vector3.up, out hit, minimumDistanceNeededToBeginFall, ignoreForGroundCheck))
{
normalVector = hit.normal;
Vector3 tp = hit.point;
playerManager.isGrounded = true;
targetPosition.y = tp.y;
if (playerManager.isInAir)
{
if (inAirTimer > 0.5f)
{
Debug.Log("You were in the air for " + inAirTimer);
animatorHandler.PlayTargetAnimation("Land", true);
inAirTimer = 0;
}
else
{
animatorHandler
.PlayTargetAnimation("Empty", false);
inAirTimer = 0;
}
playerManager.isInAir = false;
}
else
{
if (playerManager.isGrounded)
{
playerManager.isGrounded = false;
}
if (playerManager.isInAir == false)
{
if (playerManager.isInteracting == false)
{
animatorHandler
.PlayTargetAnimation("Falling", true);
}
Vector3 vel = rigidbody.velocity;
vel.Normalize();
rigidbody.velocity = vel * (movementSpeed / 2);
playerManager.isInAir = true;
}
}
if (playerManager.isInteracting || inputHandler.moveAmount > 0)
{
myTransform.position = Vector3.Lerp(myTransform.position, targetPosition, Time.deltaTime / 0.1f);
}
else
{
myTransform.position = targetPosition;
}
}
}
#endregion
}
}
Related
I make 3rd person game, where i have script for control model of my character.
Problem is that when i jump and don't push any button he stack in the air, but if i jump with pushing controlling button he worked normally.
Thanks in advance.
Player controller script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class RelativeMovement : MonoBehaviour
{
[SerializeField] private Transform target;
public float rotSpeed = 5.0f;
public float moveSpeed = 6.0f;
public float jumpSpeed = 15.0f;
public float gravity = -9.8f;
public float terminalVelocity = -20.0f;
public float minFall = -1.5f;
private float _vertSpeed;
private CharacterController _charController;
private ControllerColliderHit _contact;
void Start()
{
_vertSpeed = minFall;
_charController = GetComponent<CharacterController>();
}
void Update()
{
Vector3 movement = Vector3.zero;
float horInput = Input.GetAxis("Horizontal");
float vertInput = Input.GetAxis("Vertical");
if(horInput != 0 || vertInput != 0)
{
movement.x = horInput * moveSpeed;
movement.z = vertInput * moveSpeed;
movement = Vector3.ClampMagnitude(movement, moveSpeed);
Quaternion tmp = target.rotation;
target.eulerAngles = new Vector3(0, target.eulerAngles.y, 0);
movement = target.TransformDirection(movement);
target.rotation = tmp;
Quaternion direction = Quaternion.LookRotation(movement);
transform.rotation = Quaternion.Lerp(transform.rotation,
direction, rotSpeed * Time.deltaTime);
bool hitGround = false;
RaycastHit hit;
if(_vertSpeed < 0 && Physics.Raycast(transform.position, Vector3.down, out hit))
{
float check =
(_charController.height + _charController.radius) / 1.9f;
hitGround = hit.distance <= check;
}
if(hitGround)
{
if (Input.GetButtonDown("Jump"))
{
_vertSpeed = jumpSpeed;
}
else
{
_vertSpeed = minFall;
}
}
else
{
_vertSpeed += gravity * 5 * Time.deltaTime;
if(_vertSpeed < terminalVelocity)
{
_vertSpeed = terminalVelocity;
}
if(_charController.isGrounded)
{
if(Vector3.Dot(movement, _contact.normal) < 0)
{
movement = _contact.normal * moveSpeed;
}
else
{
movement += _contact.normal * moveSpeed;
}
}
}
movement.y = _vertSpeed;
movement *= Time.deltaTime;
_charController.Move(movement);
}
}
void OnControllerColliderHit(ControllerColliderHit hit)
{
_contact = hit;
}
}
Jesus photo:
enter image description here
I didn't go through all of the code but I can immediately see what can cause the problem you describe:
your entire logic happen under this if statement:
if(horInput != 0 || vertInput != 0)
So everything inside this logic block will happen only when you actively press a movement button.
You can remove it (or better yet, close the if block at the right spot.. I think it would be 2 lines down)
The answer of this question is:
if((horInput == 0 || vertInput == 0) || (horInput != 0 && vertInput != 0))
{
movement.x = horInput * moveSpeed;
movement.z = vertInput * moveSpeed;
if(horInput != 0 || vertInput != 0)
{
movement = Vector3.ClampMagnitude(movement, moveSpeed);
Quaternion tmp = target.rotation;
target.eulerAngles = new Vector3(0, target.eulerAngles.y, 0);
movement = target.TransformDirection(movement);
target.rotation = tmp;
Quaternion direction = Quaternion.LookRotation(movement);
transform.rotation = Quaternion.Lerp(transform.rotation,
direction, rotSpeed * Time.deltaTime);
}
Thanks Joe
Unity script error. The error occurs after adding the "extreme drift" asset.
Here is the mistake itself
"Assets\Extreme Drift\Scripts\Vehicle\VehicleCamera.cs(5,28): error CS0234: The type or namespace name 'ImageEffects' does not exist in the namespace 'UnityStandardAssets' (are you missing an assembly reference?)"
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityStandardAssets.ImageEffects;
public class VehicleCamera : MonoBehaviour
{
public static VehicleCamera manage;
public float smooth = 0.3f;
public float distance = 5.0f;
public float height = 1.0f;
public float angle = 20;
public LayerMask lineOfSightMask = 0;
[HideInInspector]
public Transform target;
[HideInInspector]
public List<Transform> cameraSwitchView;
private bool farCameraView = false;
private Vector3 farCameraPosition;
private Vector3 velocity = Vector3.zero;
private float Xsmooth;
private float farDistance = 0.0f;
private float zAngleAmount = 0.0f;
private float timeScale = 0.0f;
private float currentDistance;
private int Switch = -1;
void Awake()
{
manage = this;
farCameraPosition = transform.position;
}
void Start()
{
farCameraView = true;
farCameraPosition = (AIControl.manage.firstAINode.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode.position)
+ new Vector3(Random.Range(-5.0f, 5.0f), Random.Range(5.0f, 10.0f), Random.Range(-5.0f, 5.0f));
}
void LateUpdate()
{
if (GameUI.manage.gameFinished)
Switch = 4;
farDistance = Vector3.Distance(farCameraPosition, target.position);
if (farDistance < 100.0f && farCameraView) farCameraView = false;
transform.GetComponent<Blur>().enabled = GameUI.manage.gamePaused ? true : false;
// add MotionBlur effect to camera
if (AIControl.CurrentVehicle.shifting || GameUI.manage.driftAmount > 25)
transform.GetComponent<MotionBlur>().blurAmount = Mathf.Lerp(transform.GetComponent<MotionBlur>().blurAmount, 0.5f, Time.deltaTime * 5);
else
transform.GetComponent<MotionBlur>().blurAmount = Mathf.Lerp(transform.GetComponent<MotionBlur>().blurAmount, 0.0f, Time.deltaTime);
if (Switch == -1)
{
RenderSettings.flareStrength = 0.3f;
GetComponent<Camera>().fieldOfView = Mathf.Clamp(AIControl.CurrentVehicle.speed / 10.0f + 60.0f, 60, 90.0f);
currentDistance = distance;
float yAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y,
target.eulerAngles.y, ref velocity.y, smooth);
float xAngle = Mathf.SmoothDampAngle(transform.eulerAngles.x,
target.eulerAngles.x + (angle), ref velocity.x, smooth);
// Look at the target
transform.eulerAngles = new Vector3(xAngle, yAngle, AccelerationAngle());
Xsmooth = Mathf.Lerp(Xsmooth, velocity.y, Time.deltaTime * 10.0f);
var direction = transform.rotation * -new Vector3(-Xsmooth / 300.0f, 0, 1);
var targetDistance = AdjustLineOfSight(target.position + new Vector3(0, height, 0), direction);
transform.position = target.position + new Vector3(0, height, 0) + direction * targetDistance;
}
else if (Switch < AIControl.CurrentVehicle.cameraView.cameraSwitchView.Count)
{
RenderSettings.flareStrength = 0.3f;
GetComponent<Camera>().fieldOfView = 60;
transform.position = cameraSwitchView[Switch].position;
transform.rotation = Quaternion.Lerp(transform.rotation, cameraSwitchView[Switch].rotation, Time.deltaTime * 5.0f);
}
else {
if (farDistance > 120.0f && !farCameraView)
{
farCameraPosition = (AIControl.CurrentVehicle.AIVehicle.nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode
.GetComponent<AINode>().nextNode.position)
+ new Vector3(Random.Range(-5.0f, 5.0f), Random.Range(10.0f, 15.0f), Random.Range(-5.0f, 5.0f));
farCameraView = true;
}
RenderSettings.flareStrength = 0.0f;
GetComponent<Camera>().fieldOfView = Mathf.Clamp(50.0f - (farDistance / 2.0f), 10.0f, 120.0f);
var newRotation = Quaternion.LookRotation(target.position - transform.position);
transform.position = farCameraPosition;
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * 15);
}
}
public void CameraSwitch()
{
Switch++;
if (Switch > AIControl.CurrentVehicle.cameraView.cameraSwitchView.Count) { Switch = -1; }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private float AccelerationAngle()
{
zAngleAmount = Mathf.Clamp(zAngleAmount, -45.0f, 45.0f);
zAngleAmount = Mathf.Lerp(zAngleAmount, Input.acceleration.x * -70.0f, Time.deltaTime * 2.0f);
return zAngleAmount;
}
float AdjustLineOfSight(Vector3 target, Vector3 direction)
{
RaycastHit hit;
if (Physics.Raycast(target, direction, out hit, currentDistance, lineOfSightMask.value))
return hit.distance;
else
return currentDistance;
}
}
As I understand it, you need to connect the "Standard assets" to the project, I connected it, but it still does not work.
I am trying to make a simple pong game where once the player or the enemy scores both of them get repositioned on the field.
I have this script on the enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBehavior : MonoBehaviour
{
Vector3 ballPosition;
Vector3 paddlePosition;
float movementSpeed = 0.1f;
public Transform target;
public float maxAngle = 35.0f;
private Quaternion baseRotation;
private Quaternion targetRotation;
// Start is called before the first frame update
void Start()
{
baseRotation = transform.rotation;
}
// Update is called once per frame
void Update()
{
ballPosition = GameObject.Find("Ball").transform.position;
paddlePosition = this.transform.position;
if (paddlePosition.z < ballPosition.z)
{
paddlePosition.z += movementSpeed;
}
else if (paddlePosition.z > ballPosition.z)
{
paddlePosition.z -= movementSpeed;
}
transform.position = paddlePosition;
Vector3 look = target.transform.position - transform.position;
look.z = 0;
Quaternion q = Quaternion.LookRotation(look);
if (Quaternion.Angle(q, baseRotation) <= maxAngle)
{
targetRotation = q;
}
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0f);
}
}
And then a goal script attached to the goal that looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Goal : MonoBehaviour
{
public GameObject Ball;
public GameObject Player;
public GameObject Enemy;
public Text Player2Score;
public Text Player1Score;
int Player2ScoreText = 0;
int Player1ScoreText = 0;
Rigidbody ballrig;
Rigidbody playerrig;
Rigidbody enemyrig;
public ParticleSystem Particles;
float timeLeft = 1.0f;
public bool slowMo = false;
// Start is called before the first frame update
void Start()
{
ballrig = Ball.GetComponent<Rigidbody>();
playerrig = Player.GetComponent<Rigidbody>();
enemyrig = Enemy.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (slowMo == true)
{
timeLeft -= Time.deltaTime;
if (timeLeft < 0)
{
slowMo = false;
timeLeft = 1.0f;
Time.timeScale = 1f;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.name == "Ball" && name == "Player_Goal")
{
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player2ScoreText += 1;
Player2Score.text = ("" + Player2ScoreText);
Ball.transform.position = new Vector3(0f, 4f, 0f);
Player.transform.position = new Vector3(-20f, 2f, 0f);
Enemy.transform.position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
if (whoGetsIt >= 1)
{
Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
else
{
Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
}
else if (other.name == "Ball" && name == "Enemy_Goal")
{
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player1ScoreText += 1;
Player1Score.text = ("" + Player1ScoreText);
Ball.transform.position = new Vector3(0f, 4f, 0f);
Player.transform.position = new Vector3(-20f, 2f, 0f);
Enemy.transform.position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
if (whoGetsIt >= 1)
{
Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
else
{
Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
}
}
}
void Explode()
{
Particles.Play();
}
}
Now the ball gets repositioned correctly after someone scores but for some reason the player and the enemy do not.
Is it because they both have code in their update function so that code "overwrights" the repositioned command? And if so how can I get around that?
I can see that your players are using Rigidbody or Rigidbody2D.
Whenever a rigidbody is involved you should not set any position via transform but rather use the according rigidbody methods like MovePosition and MoveRotation or for directly setting them go through Rigibody.position and Rigidbody.rotation e.g.
....
slowMo = true;
Time.timeScale = 0.5f;
Explode();
Player2ScoreText += 1;
Player2Score.text = ("" + Player2ScoreText);
Ball.GetComponent<Rigidbody>().position = new Vector3(0f, 4f, 0f);
Player.GetComponent<Rigidbody>().position = new Vector3(-20f, 2f, 0f);
Enemy.GetComponent<Rigidbody>().position = new Vector3(20f, 2f, 0f);
ballrig.velocity = Vector3.zero;
ballrig.angularVelocity = Vector3.zero;
playerrig.velocity = Vector3.zero;
playerrig.angularVelocity = Vector3.zero;
enemyrig.velocity = Vector3.zero;
enemyrig.angularVelocity = Vector3.zero;
int whoGetsIt = Random.Range(0, 2);
....
And then also in the EnemyBehaviour -> It should be FixedUpdate and look like
public Rigidbody target;
Rigidbody ball;
Rigidbody ownRigidbody;
void Start()
{
baseRotation = transform.rotation;
// Get reference only ONCE and store them1
ball = GameObject.Find("Ball").GetComponent<Rigidbody>();
ownRigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
ballPosition = ball.position;
paddlePosition = ownRigidbody.position;
if (paddlePosition.z < ballPosition.z)
{
paddlePosition.z += movementSpeed;
}
else if (paddlePosition.z > ballPosition.z)
{
paddlePosition.z -= movementSpeed;
}
ownRigidbody.MovePosition(paddlePosition;)
Vector3 look = target.position - ownRigidbody.position;
look.z = 0;
Quaternion q = Quaternion.LookRotation(look);
if (Quaternion.Angle(q, baseRotation) <= maxAngle)
{
targetRotation = q;
}
ownRigidbody.MoveRotation(Quaternion.Slerp(ownRigidbody.rotation, targetRotation, Time.deltaTime * 2.0f));
}
since here you want smooth interpolated position
I am currently in the process of developing my first platformer, and I've decided that I want to bake my own acceleration and deceleration for movement instead of using unity's wonky physics.
This has brought up two roadblocks, one being that my character will just clip through objects like walls to jump over or off of, and the other is that if I try to switch directions while decelerating, my character will turn around, but it won't change directions and my acceleration will bypass the limit I set for it (in layman's, it zooms backwards).
I need help fixing this and can describe any of the functions of the variables if asked. There is no physics material on my character, and I am using physics for the jump.
All of the variables are defined in the unity editor for easier tweaking except for currentSpeed, jumpCount, FallTime and canJump, which I have serialized so I can observe them during testing.
I've tried changing
newPos = new Vector2(transform.position.x + currentSpeed, transform.position.y);
transform.position = newPos;
to addForce but it messed with the jumping.
public class PlayerControls : MonoBehaviour {
//walk Vars
[SerializeField] float currentSpeed;
[SerializeField] float maxSpeed;
[SerializeField] float jumpstart;
[SerializeField] float acceleration;
[SerializeField] float deceleraton;
int isFlip = 1;
Vector2 newPos;
Quaternion flip;
//jump Vars
[SerializeField] public int jumpCount;
[SerializeField] public int jumpCountMax;
[SerializeField] public float jumpVel;
[SerializeField] public float fallMulti;
[SerializeField] public float shortMulti;
[SerializeField] public float fallTime;
[SerializeField] public float coyoteTime;
[SerializeField] bool canJump = true;
[SerializeField] bool didJump;
//references
Rigidbody2D rb;
private void Awake() {
rb = GetComponent<Rigidbody2D>();
}
//walk Functions
private void speedCalc() {
currentSpeed += jumpstart * isFlip;
if (currentSpeed * isFlip >= maxSpeed) {
currentSpeed = maxSpeed * isFlip;
}
else {
currentSpeed = (currentSpeed * acceleration);
}
}
private void Start() {
currentSpeed = 0;
}
private void Update() {
//calculate coyote time
if (fallTime == coyoteTime) {
if (didJump == false) {
jumpCount += 1;
}
}
if (jumpCount >= jumpCountMax) {
canJump = false;
} else {
canJump = true;
}
if (rb.velocity.y == 0) {
jumpCount = 0;
didJump = false;
}
//calculate isFlip
if (Input.GetButton("Right")) {
flip = Quaternion.Euler(0, 0, 0);
transform.rotation = flip;
isFlip = 1;
} else if (Input.GetButton("Left")) {
flip = Quaternion.Euler(0, 180, 0);
transform.rotation = flip;
isFlip = -1;
}
//calculate acceleration & deceleration
if (!Input.GetButton("Right") && !Input.GetButton("Left")) {
if (currentSpeed * isFlip <= jumpstart) {
currentSpeed = 0;
} else {
currentSpeed = (currentSpeed / deceleraton);
}
} else {
speedCalc();
}
//implement falling and dyanamic jumping
if (rb.velocity.y < 0) {
fallTime += 1;
rb.velocity += Vector2.up * Physics2D.gravity * (fallMulti - 1) * Time.deltaTime;
} else if (rb.velocity.y == 0) {
fallTime = 0;
} else if (rb.velocity.y > 0 && !Input.GetButton("Jump")) {
rb.velocity += Vector2.up * Physics2D.gravity * (shortMulti - 1) * Time.deltaTime;
}
//execute jump
if (Input.GetButtonDown("Jump") && canJump == true) {
didJump = true;
rb.velocity = Vector2.up * jumpVel;
jumpCount += 1;
}
//move character position
newPos = new Vector2(transform.position.x + currentSpeed, transform.position.y);
transform.position = newPos;
}
}
There where no error messages or anything but I'm 80% sure its my logic and ordering. The acceleration might be overlapping with the deceleration and the isFlip.
I'm working on terrain and I made this pit and my character controller acts like
it is on ground but its floating for sure and when I move forward it will get dragged down by the gravity but it gets "stuck" again floating and if I'm on the bottom of the pit and try to climb it it actually climbs the big slop while my slop limit is 45 and it counts like its grounded so I can jump again and yea I tried making a raycast to check if its grounded but still it only fixes the problem with climbing but it still if I jump at the sides of the pit I will start floating.
Here is the script .
using UnityEngine;
using System.Collections;
public class moveController : MonoBehaviour
{
private CharacterController controller;
public float moveSpeed = 15f;
public float jumpForce = 15f;
private Vector3 moveDirection;
private float gravityScale = 0.1f;
private float up_Down;
private float right_Left;
private float mouseX;
private float mouseY;
//headbob
private float currentAngle = 0;
private float smooth = 20.0F;
private float tiltAngle = 1.0F;
private float tiltAroundZ;
Vector3 h_bob;
//AccelerationVariables
private float jumpVelocityPerSecond = 3f;
private float speedVelocityPerSecond = 3f;
// jump or not , moving or not , walking or not,
private bool isJumping;
private bool isMoving;
private bool isWalking;
// look variables
Vector2 mouselook;
Vector2 smoothV;
private float smoothing = 2f;
private float sensitivity = 1.5f;
private Camera eyes;
private void Awake()
{
controller = GetComponent<CharacterController>();
eyes = Camera.main;
}
void Start()
{
}
void Update()
{
Move();
SlowDown();
//DeadHop();
// MaxSpeed_Jump();
Crouch();
}
private void Move()
{
// moveDirection = new Vector3(Input.GetAxis("Horizontal") * moveSpeed, moveDirection.y, Input.GetAxis("Vertical") * moveSpeed);
up_Down = Input.GetAxis("Vertical");
right_Left = Input.GetAxis("Horizontal");
mouseX = Input.GetAxis("Mouse X");
mouseY = Input.GetAxis("Mouse Y");
tiltAroundZ = Input.GetAxis("Horizontal") * tiltAngle;
currentAngle = Mathf.MoveTowards(currentAngle, tiltAroundZ, Time.deltaTime * smooth);
Vector3 moveDirSide = transform.right * right_Left * moveSpeed;
Vector3 moveDirForward = transform.forward * up_Down * moveSpeed ;
Vector3 BodyRot = transform.rotation.eulerAngles;
BodyRot.y += mouseX;
var md = new Vector2(mouseX, mouseY);
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouselook += smoothV;
mouselook.y = Mathf.Clamp(mouselook.y, -80f, 80f);
// check if he is moving
if (Input.GetButton("Horizontal"))
{
isMoving = true;
}
else if (Input.GetButton("Vertical"))
{
isMoving = true;
}
else
{
isMoving = false;
}
// check if he is jumping
if (Input.GetButton("Jump"))
{
isJumping = true;
}
else if (Input.GetButtonUp("Jump"))
{
isJumping = false;
}
///check if grounded so he can jump
if (controller.isGrounded)
{
if (isJumping)
{
moveDirection.y = jumpForce;
}
}
moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale);
controller.Move(moveDirSide * Time.deltaTime);
controller.Move(moveDirForward * Time.deltaTime);
controller.Move(moveDirection * Time.deltaTime);
eyes.transform.localRotation = Quaternion.Euler(-mouselook.y, Vector3.right.x, -currentAngle);
transform.localRotation = Quaternion.AngleAxis(mouselook.x, BodyRot);
}
a
private void SlowDown()
{
if (Input.GetButton("SlowDown"))
{
moveSpeed = 5f;
jumpForce = 10f;
isWalking = true;
}
else if (Input.GetButtonUp("SlowDown"))
{
moveSpeed = 15f;
jumpForce = 15f;
isWalking = false;
}
}
//private void DeadHop()
//{
// if (isMoving)
// {
// jumpForce += jumpVelocityPerSecond * Time.deltaTime ;
// moveSpeed += speedVelocityPerSecond * Time.deltaTime ;
// }
// else if (isMoving == false)
// {
// jumpForce = 10f;
// moveSpeed = 10f;
// }
//}
//private void MaxSpeed_Jump()
//{
// if(moveSpeed >= 15)
// {
// moveSpeed = 15;
// }
// if(jumpForce >= 15)
// {
// jumpForce = 15;
// }
//}
private void Crouch()
{
if (Input.GetButton("Crouch") && isJumping == false)
{
controller.height = 1.5f;
moveSpeed = 5f;
}
else if (Input.GetButtonUp("Crouch") && isJumping == false)
{
moveSpeed = 15f;
controller.height = 3f;
}
if (Input.GetButton("Crouch") && isJumping == true)
{
controller.height = 1.5f;
}
else if (Input.GetButtonUp("Crouch") && isJumping == true)
{
moveSpeed = 15f;
controller.height = 3f;
}
}
}