I need to rotate car along the path, but the code doesn't work correct. It moves as a firework. I guess that the problem is in moving from z to x axis. I dont have enough knowledge to solve this problem. Help!
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public Transform StartPoint;
public Transform[] EndPoints;
public Transform[] AngleWaypoints;
public float MoveSpeed;
private Transform TargetPoint;
//private Transform EndPoint;
private float DistanceToPoint = 0f;
private int RandomValue;
private Transform[] Waypoints;
private int wpIndex = 0;
private Quaternion lookRotation;
private Vector3 direction;
// Use this for initialization
void Start ()
{
RandomValue = Random.Range (1, EndPoints.Length);
int count = 0;
switch (RandomValue) {
case 0:
//Waypoints = StartPoint + EndPoints [RandomValue];
count = 2;
Waypoints = new Transform[count];
Waypoints [0] = StartPoint;
Waypoints [1] = EndPoints[RandomValue];
break;
case 1:
//Waypoints = StartPoint + AngleWaypoints + EndPoints[RandomValue];
count = 2 + AngleWaypoints.Length;
Waypoints = new Transform[count];
Waypoints [0] = StartPoint;
for(int i=0;i<AngleWaypoints.Length;i++){
Waypoints [i + 1] = AngleWaypoints [i];
}
Waypoints [count-1] = EndPoints[RandomValue];
break;
}
TargetPoint = Waypoints [wpIndex];
}
// Update is called once per frame
void Update ()
{
DistanceToPoint = Vector3.Distance (transform.position, TargetPoint.position);
if (DistanceToPoint > 1) {
direction = (TargetPoint.position - transform.position)/2 + transform.position;
Vector3 dir = TargetPoint.position - transform.position;
lookRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp (transform.rotation, lookRotation, Time.deltaTime);
Vector3 v = direction / DistanceToPoint * MoveSpeed * Time.deltaTime;
transform.Translate (v);
} else {
wpIndex++;
if (wpIndex > Waypoints.Length - 1) {
wpIndex = 0;
Destroy(this.gameObject);
}
TargetPoint = Waypoints[wpIndex];
}
}
}
I used this code sometime ago and it worked
void Update () {
if (this.isMoving){
if(Vector3.Distance(walkDestination, transform.position) > 0.2f){
float step = 0f;
step = this.speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, walkDestination, step);
Vector3 rotationDestination = this.rotateDestination;
Quaternion targetRotation = Quaternion.LookRotation(rotationDestination - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 6.0f);
}else{
//Arrived to destination
}
}
}
Related
So, apperently I am trying to make a game using unity.
So far so good.
But there is one problem: Everytime I crouch or slide, I cant move anymore until I stand up again.
I ve tried everything.
I ve even tried removing the sliding completely or writing a whole new code, yet nothing works.
Sorry for the long code, but I dont know anymore ;-;
using System;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
//Assingables
public Transform playerCam;
public Transform orientation;
//Other
private Rigidbody rb;
//Rotation and look
private float xRotation;
private float sensitivity = 50f;
public float sensMultiplier = 1f;
//Movement
public float moveSpeed = 4500;
public float maxSpeed = 10;
public bool grounded;
public LayerMask whatIsGround;
public float counterMovement = 0.175f;
private float threshold = 0.01f;
public float maxSlopeAngle = 35f;
public float sprintspeed = 20f;
public float speedOrigin = 10f;
//Crouch & Slide
private Vector3 crouchScale = new Vector3(1, 0.5f, 1);
private Vector3 playerScale;
public float slideForce = 0;
public float slideCounterMovement = 0.2f;
//Jumping
private bool readyToJump = true;
private float jumpCooldown = 0.25f;
public float jumpForce = 300f;
//Input
float x, y;
bool jumping, sprinting, crouching;
//Sliding
private Vector3 normalVector = Vector3.up;
private Vector3 wallNormalVector;
void Awake() {
rb = GetComponent<Rigidbody>();
}
void Start() {
playerScale = transform.localScale;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
private void FixedUpdate() {
Movement();
}
private void Update() {
MyInput();
Look();
}
/// <summary>
/// Find user input. Should put this in its own class but im lazy
/// </summary>
private void MyInput() {
x = Input.GetAxisRaw("Horizontal");
y = Input.GetAxisRaw("Vertical");
jumping = Input.GetButton("Jump");
crouching = Input.GetKey(KeyCode.LeftControl);
//Sprinting
if (Input.GetKeyDown(KeyCode.LeftShift) && !crouching)
StartSprint();
if (Input.GetKeyUp(KeyCode.LeftShift))
StopSprint();
//Crouching
if (Input.GetKeyDown(KeyCode.LeftControl))
StartCrouch();
if (Input.GetKeyUp(KeyCode.LeftControl))
StopCrouch();
}
private void StartCrouch() {
transform.localScale = crouchScale;
transform.position = new Vector3(transform.position.x, transform.position.y - 0.5f, transform.position.z);
maxSpeed = 7f;
}
private void StopCrouch() {
transform.localScale = playerScale;
transform.position = new Vector3(transform.position.x, transform.position.y + 0.5f, transform.position.z);
maxSpeed = speedOrigin;
}
//Sprinting
private void StartSprint() {
maxSpeed = sprintspeed;
}
private void StopSprint() {
maxSpeed = speedOrigin;
}
private void Movement() {
//Extra gravity
rb.AddForce(Vector3.down * Time.deltaTime * 10);
//Find actual velocity relative to where player is looking
Vector2 mag = FindVelRelativeToLook();
float xMag = mag.x, yMag = mag.y;
//Counteract sliding and sloppy movement
CounterMovement(x, y, mag);
//If holding jump && ready to jump, then jump
if (readyToJump && jumping) Jump();
//Set max speed
float maxSpeed = this.maxSpeed;
//If sliding down a ramp, add force down so player stays grounded and also builds speed
if (crouching && grounded && readyToJump) {
rb.AddForce(Vector3.down * Time.deltaTime * 3000);
return;
}
//If speed is larger than maxspeed, cancel out the input so you don't go over max speed
if (x > 0 && xMag > maxSpeed) x = 0;
if (x < 0 && xMag < -maxSpeed) x = 0;
if (y > 0 && yMag > maxSpeed) y = 0;
if (y < 0 && yMag < -maxSpeed) y = 0;
//Some multipliers
float multiplier = 1f, multiplierV = 1f;
// Movement in air
if (!grounded) {
maxSpeed = 8f;
}
// Movement while crouching
if (grounded && crouching) maxSpeed = 7f;
//Apply forces to move player
rb.AddForce(orientation.transform.forward * y * moveSpeed * Time.deltaTime * multiplier * multiplierV);
rb.AddForce(orientation.transform.right * x * moveSpeed * Time.deltaTime * multiplier);
}
private void Jump() {
if (grounded && readyToJump) {
readyToJump = false;
//Add jump forces
rb.AddForce(Vector2.up * jumpForce * 1.5f);
rb.AddForce(normalVector * jumpForce * 0.5f);
//If jumping while falling, reset y velocity.
Vector3 vel = rb.velocity;
if (rb.velocity.y < 0.5f)
rb.velocity = new Vector3(vel.x, 0, vel.z);
else if (rb.velocity.y > 0)
rb.velocity = new Vector3(vel.x, vel.y / 2, vel.z);
Invoke(nameof(ResetJump), jumpCooldown);
}
}
private void ResetJump() {
readyToJump = true;
}
private float desiredX;
private void Look() {
float mouseX = Input.GetAxis("Mouse X") * sensitivity * Time.fixedDeltaTime * sensMultiplier;
float mouseY = Input.GetAxis("Mouse Y") * sensitivity * Time.fixedDeltaTime * sensMultiplier;
//Find current look rotation
Vector3 rot = playerCam.transform.localRotation.eulerAngles;
desiredX = rot.y + mouseX;
//Rotate, and also make sure we dont over- or under-rotate.
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
//Perform the rotations
playerCam.transform.localRotation = Quaternion.Euler(xRotation, desiredX, 0);
orientation.transform.localRotation = Quaternion.Euler(0, desiredX, 0);
}
private void CounterMovement(float x, float y, Vector2 mag) {
if (!grounded || jumping) return;
//Slow down sliding
if (crouching) {
rb.AddForce(moveSpeed * Time.deltaTime * -rb.velocity.normalized * slideCounterMovement);
return;
}
//Counter movement
if (Math.Abs(mag.x) > threshold && Math.Abs(x) < 0.05f || (mag.x < -threshold && x > 0) || (mag.x > threshold && x < 0)) {
rb.AddForce(moveSpeed * orientation.transform.right * Time.deltaTime * -mag.x * counterMovement);
}
if (Math.Abs(mag.y) > threshold && Math.Abs(y) < 0.05f || (mag.y < -threshold && y > 0) || (mag.y > threshold && y < 0)) {
rb.AddForce(moveSpeed * orientation.transform.forward * Time.deltaTime * -mag.y * counterMovement);
}
//Limit diagonal running. This will also cause a full stop if sliding fast and un-crouching, so not optimal.
if (Mathf.Sqrt((Mathf.Pow(rb.velocity.x, 2) + Mathf.Pow(rb.velocity.z, 2))) > maxSpeed) {
float fallspeed = rb.velocity.y;
Vector3 n = rb.velocity.normalized * maxSpeed;
rb.velocity = new Vector3(n.x, fallspeed, n.z);
}
}
/// <summary>
/// Find the velocity relative to where the player is looking
/// Useful for vectors calculations regarding movement and limiting movement
/// </summary>
/// <returns></returns>
public Vector2 FindVelRelativeToLook() {
float lookAngle = orientation.transform.eulerAngles.y;
float moveAngle = Mathf.Atan2(rb.velocity.x, rb.velocity.z) * Mathf.Rad2Deg;
float u = Mathf.DeltaAngle(lookAngle, moveAngle);
float v = 90 - u;
float magnitue = rb.velocity.magnitude;
float yMag = magnitue * Mathf.Cos(u * Mathf.Deg2Rad);
float xMag = magnitue * Mathf.Cos(v * Mathf.Deg2Rad);
return new Vector2(xMag, yMag);
}
private bool IsFloor(Vector3 v) {
float angle = Vector3.Angle(Vector3.up, v);
return angle < maxSlopeAngle;
}
private bool cancellingGrounded;
/// <summary>
/// Handle ground detection
/// </summary>
private void OnCollisionStay(Collision other) {
//Make sure we are only checking for walkable layers
int layer = other.gameObject.layer;
if (whatIsGround != (whatIsGround | (1 << layer))) return;
//Iterate through every collision in a physics update
for (int i = 0; i < other.contactCount; i++) {
Vector3 normal = other.contacts[i].normal;
//FLOOR
if (IsFloor(normal)) {
grounded = true;
cancellingGrounded = false;
normalVector = normal;
CancelInvoke(nameof(StopGrounded));
}
}
//Invoke ground/wall cancel, since we can't check normals with CollisionExit
float delay = 3f;
if (!cancellingGrounded) {
cancellingGrounded = true;
Invoke(nameof(StopGrounded), Time.deltaTime * delay);
}
}
private void StopGrounded() {
grounded = false;
}
}
Have you tried to delete the return inside this?
if (crouching && grounded && readyToJump) {
rb.AddForce(Vector3.down * Time.deltaTime * 3000);
return;
}
Because of that, you are not applying force for move your object based on your inputs.
Hello I am trying to move a game object in 3d space I have searched the internet and found there are 3 ways to do that using turntoface(euler angles) or quaternion or navmesh agents
My problem is the game object default rotation is changing in using quaternions or move towards.
Can anyone help me understand why it is happening like that.
I want the capsule in slanted position.
//below code is using quaternions
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Guard : MonoBehaviour
{
public float speed = 5;
public float waitTime = .3f;
public float turnSpeed = 90;
public Transform pathHolder;
public Transform target;
void Start()
{
Vector3[] waypoints = new Vector3[pathHolder.childCount];
for (int i = 0; i < waypoints.Length; i++)
{
waypoints = pathHolder.GetChild(i).position;
waypoints = new Vector3(waypoints.x, transform.position.y, waypoints.z);
}
StartCoroutine(FollowPath(waypoints));
}
IEnumerator FollowPath(Vector3[] waypoints)
{
transform.position = waypoints[0];
int targetWaypointIndex = 1;
Vector3 targetWaypoint = waypoints[targetWaypointIndex];
while (true)
{
Quaternion targetRotation = Quaternion.LookRotation(targetWaypoint - transform.position);
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
if (transform.rotation == targetRotation)
{
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint, speed * Time.deltaTime);
if (transform.position == targetWaypoint)
{
targetWaypointIndex = (targetWaypointIndex + 1) % waypoints.Length;
targetWaypoint = waypoints[targetWaypointIndex];
yield return new WaitForSeconds(waitTime);
}
}
yield return null;
}
IEnumerator TurnToFace(Vector3 lookTarget)
{
Vector3 dirToLookTarget = (lookTarget - transform.position).normalized;
float targetAngle = 90 - Mathf.Atan2(dirToLookTarget.y, dirToLookTarget.x) * Mathf.Rad2Deg;
while (Mathf.Abs(Mathf.DeltaAngle(transform.eulerAngles.y, targetAngle)) > 0.05f)
{
float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, targetAngle, turnSpeed * Time.deltaTime);
transform.eulerAngles = Vector3.up * angle;
yield return null;
}
}
void OnDrawGizmos()
{
Vector3 startPosition = pathHolder.GetChild(0).position;
Vector3 previousPosition = startPosition;
foreach (Transform waypoint in pathHolder)
{
Gizmos.DrawSphere(waypoint.position, .3f);
Gizmos.DrawLine(previousPosition, waypoint.position);
previousPosition = waypoint.position;
}
Gizmos.DrawLine(previousPosition, startPosition);
}
}
}
//below code is using turntoface (euler angles concept)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Guard : MonoBehaviour
{
public float speed = 5;
public float waitTime = .3f;
public float turnSpeed = 90;
public Transform pathHolder;
void Start()
{
Vector3[] waypoints = new Vector3[pathHolder.childCount];
for (int i = 0; i < waypoints.Length; i++)
{
waypoints = pathHolder.GetChild(i).position;
waypoints = new Vector3(waypoints.x, transform.position.y, waypoints.z);
}
StartCoroutine(FollowPath(waypoints));
}
IEnumerator FollowPath(Vector3[] waypoints)
{
transform.position = waypoints[0];
int targetWaypointIndex = 1;
Vector3 targetWaypoint = waypoints[targetWaypointIndex];
transform.LookAt(targetWaypoint);
while (true)
{
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint, speed * Time.deltaTime);
if (transform.position == targetWaypoint)
{
targetWaypointIndex = (targetWaypointIndex + 1) % waypoints.Length;
targetWaypoint = waypoints[targetWaypointIndex];
yield return new WaitForSeconds(waitTime);
yield return StartCoroutine(TurnToFace(targetWaypoint));
}
yield return null;
}
}
IEnumerator TurnToFace(Vector3 lookTarget)
{
Vector3 dirToLookTarget = (lookTarget - transform.position).normalized;
float targetAngle = 90 - Mathf.Atan2(dirToLookTarget.z, dirToLookTarget.x) * Mathf.Rad2Deg;
while (Mathf.DeltaAngle(transform.eulerAngles.y, targetAngle) > 0.05f)
{
float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, targetAngle, turnSpeed * Time.deltaTime);
transform.eulerAngles = Vector3.up * angle;
yield return null;
}
}
void OnDrawGizmos()
{
Vector3 startPosition = pathHolder.GetChild(0).position;
Vector3 previousPosition = startPosition;
foreach (Transform waypoint in pathHolder)
{
Gizmos.DrawSphere(waypoint.position, .3f);
Gizmos.DrawLine(previousPosition, waypoint.position);
previousPosition = waypoint.position;
}
Gizmos.DrawLine(previousPosition, startPosition);
}
}
This link has all videos and required output for reference
so what I want is when the mouse is on the left the object switches to the left and when the mouse is on the right the weapon faces the right. Got any ideas??
public class WeaponParent : MonoBehaviour
{
public float blahblah = 90;
void Update()
{
faceMouse();
}
void faceMouse()
{
Vector2 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle -blahblah, Vector3.forward);
transform.rotation = rotation;
}
Hey guys, I figured it out.
{
public float blahblah = 90;
public float offset = 3f;
private SpriteRenderer spriteRender;
public SpriteRenderer brat;
private void Start()
{
spriteRender = GetComponent<SpriteRenderer>();
}
void Update()
{
faceMouse();
}
void faceMouse()
{
// Vector2 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
// float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
// Quaternion rotation = Quaternion.AngleAxis(angle -blahblah, Vector3.forward);
// transform.rotation = rotation;
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rot2 = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rot2);
if(rot2 < 69 && rot2 > -69)
{
Debug.Log("Facing right");
transform.localScale = new Vector3(1, 1, 1);
brat.flipX = false;
}
else
{
Debug.Log("Facing left");
transform.localScale = new Vector3(1, -1, 1);
brat.flipX = true;
}
}
}
My playable character turns left or right when it meets an obstacle with a collider. It's normal but I want to know if there is a way to disable it.
this is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMotor : MonoBehaviour
{
public Vector3 startPosition;
private const float LANE_DISTANCE = 3.0f;
private const float TURN_SPEED = 0.5f;
//Functionality
private bool isRunning = false;
public bool isClimbing = false;
private readonly object down;
private CharacterController controller;
[SerializeField]
private float jumpForce = 5.0f;
private float verticalVelocity = 0.0f;
private float gravity = 10.0f;
//Speed
private float originalSpeed = 4.0f;
private float speed = 4.0f;
private float speedIncreaseLastTick;
private float speedIncreaseTime = 2.5f;
private float speedIncreaseAmount = 0.1f;
private float climbingSpeed = 1.0f;
private int desiredLane = 0; //0 = left, 1 = middle, 2 = right
private Animator anim;
// Start is called before the first frame update
void Start()
{
speed = originalSpeed;
controller = GetComponent<CharacterController>();
anim = GetComponent<Animator>();
transform.position = startPosition;
}
// Update is called once per frame
void Update()
{
if (isClimbing)
{
transform.Translate(Vector3.up * climbingSpeed * Time.deltaTime);
}
if (!isRunning)
return;
if (Time.time - speedIncreaseLastTick > speedIncreaseTime)
{
speedIncreaseLastTick = Time.time;
speed += speedIncreaseAmount;
//GameManager.Instance.UpdateScores();
}
// Gather the inputs on wich lane we should be
if (MobileInput.Instance.SwipeLeft)
{
MoveLane(false);
}
if (MobileInput.Instance.SwipeRight)
{
MoveLane(true);
}
// Calculate where we should be horizontally
Vector3 targetPosition = transform.position.z * Vector3.forward;
int posX = Mathf.Abs(desiredLane);
if (desiredLane < 0)
targetPosition += Vector3.left * posX * LANE_DISTANCE;
else if (desiredLane > 0)
targetPosition += Vector3.right * posX * LANE_DISTANCE;
//Calculate move delta
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetPosition - transform.position).normalized.x * speed;
bool isGrounded = IsGrounded();
anim.SetBool("Grounded", isGrounded);
//Calculate y
if (isGrounded) //If grounded
{
verticalVelocity = -0.1f;
if (MobileInput.Instance.SwipeUp)
{
//Jump
anim.SetTrigger("Jump");
verticalVelocity = jumpForce;
}
else if (MobileInput.Instance.SwipeDown)
{
//Slide
StartSliding();
Invoke("StopSliding", 1.0f);
}
}
else
{
verticalVelocity -= (gravity * Time.deltaTime);
//Fast falling machanics
if (MobileInput.Instance.SwipeDown)
{
verticalVelocity = -jumpForce;
}
}
moveVector.y = verticalVelocity;
moveVector.z = speed;
//Move the character
controller.Move(moveVector * Time.deltaTime);
//Rotate the player where is going
Vector3 dir = controller.velocity;
if (dir!= Vector3.zero)
{
dir.y = 0;
transform.forward = Vector3.Lerp(transform.forward, dir, TURN_SPEED);
}
}
// This function (MoveLane) allows the player to move to the left and to the right
private void MoveLane(bool goingRight)
{
if (!goingRight)
{
desiredLane--;
if (desiredLane == -6)
desiredLane = -5;
}
if (goingRight)
{
desiredLane++;
if (desiredLane == 6)
desiredLane = 5;
}
/* We wan rewrite the above function like this below
desiredLane += (goingRight) ? 1 : -1;
Mathf.Clamp(desiredLane, -5, 5);
*/
}
private bool IsGrounded()
{
Ray groundRay = new Ray(new Vector3(controller.bounds.center.x, (controller.bounds.center.y - controller.bounds.extents.y) + 0.2f,
controller.bounds.center.z), Vector3.down);
Debug.DrawRay(groundRay.origin, groundRay.direction, Color.cyan, 1.0f);
return (Physics.Raycast(groundRay, 0.2f + 0.1f));
}
public void StartRunning ()
{
isRunning = true;
anim.SetTrigger("StartRunning");
}
private void StartSliding()
{
anim.SetBool("Sliding", true);
controller.height /= 2;
controller.center = new Vector3(controller.center.x, controller.center.y / 2, controller.center.z);
}
private void StopSliding()
{
anim.SetBool("Sliding", false);
controller.height *= 2;
controller.center = new Vector3(controller.center.x, controller.center.y * 2, controller.center.z);
}
private void Crash()
{
anim.SetTrigger("Death");
isRunning = false;
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
switch(hit.gameObject.tag)
{
case "Obstacle":
Crash();
break;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Ladder")
{
isRunning = false;
isClimbing = true;
anim.SetBool("ClimbingLadder", true);
}
else if (other.gameObject.tag == "LadderCol2")
{
isClimbing = false;
anim.SetBool("ClimbingLadder", false);
transform.Translate(Vector3.forward * 1);
isRunning = true;
}
}
}
I see the problem. It's from these lines
Vector3 dir = controller.velocity;
if (dir!= Vector3.zero)
{ dir.y = 0;
transform.forward =
Vector3.Lerp(transform.forward, dir,
TURN_SPEED);
}
I added them to rotate a bit the player when it turns left or right.
I am trying to make a player movement controller like subway surfer using Character Controller, every thing is working fine with keyboard but I am getting an issue in swipe. When I swipe its moving only one frame. And also I want player to go left and right while player in air(Jumping). Please help.
Here is my code:
using UnityEngine;
using System.Collections;
public class PlayerControllerScript : MonoBehaviour
{
public float speed = 8.0F;
public float jumpSpeed = 16.0F;
public float gravity = 80.0F;
private Vector3 moveDirection = Vector3.zero;
public int laneNumber = 1;
public int lanesCount = 3;
bool didChangeLastFrame = false;
public float laneDistance = 2;
public float firstLaneXPos = -2;
public float deadZone = 0.1f;
public float sideSpeed = 12;
private bool Right = false;
private bool Left = false;
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
float input = Input.GetAxis("Horizontal");
if (controller.isGrounded) {
if (Mathf.Abs(input) > deadZone)
{
if (!didChangeLastFrame)
{
didChangeLastFrame = true;
laneNumber += Mathf.RoundToInt(Mathf.Sign(input));
if (laneNumber < 0) laneNumber = 0;
else if (laneNumber >= lanesCount) laneNumber = lanesCount - 1;
}
}
else
{
didChangeLastFrame = false;
moveDirection = new Vector3(0, 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
}
}
if (Left)
moveDirection.x = -jumpSpeed;
if (Right)
moveDirection.x = jumpSpeed;
if (SwipeManager.IsSwipingLeft())
{
Left = true;
Right = false;
}
if (SwipeManager.IsSwipingRight())
{
Right = true;
Left = false;
}
Vector3 pos = transform.position;
pos.x = Mathf.Lerp(pos.x, firstLaneXPos + laneDistance * laneNumber, Time.deltaTime * sideSpeed);
transform.position = pos;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}
I think,
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
must be outside the if(controller.isGrounded) block. So, you jump regardless of gravity.
This is the final code;
using UnityEngine;
using System.Collections;
public class PlayerControllerScript : MonoBehaviour
{
public float speed = 8.0F;
public float jumpSpeed = 16.0F;
public float gravity = 80.0F;
private Vector3 moveDirection = Vector3.zero;
public int laneNumber = 1;
public int lanesCount = 3;
bool didChangeLastFrame = false;
public float laneDistance = 2;
public float firstLaneXPos = -2;
public float deadZone = 0.1f;
public float sideSpeed = 12;
private bool Right = false;
private bool Left = false;
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
float input = Input.GetAxis("Horizontal");
if (controller.isGrounded) {
if (Mathf.Abs(input) > deadZone)
{
if (!didChangeLastFrame)
{
didChangeLastFrame = true;
laneNumber += Mathf.RoundToInt(Mathf.Sign(input));
if (laneNumber < 0) laneNumber = 0;
else if (laneNumber >= lanesCount) laneNumber = lanesCount - 1;
}
}
else
{
didChangeLastFrame = false;
moveDirection = new Vector3(0, 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
}
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
if (Left)
moveDirection.x = -jumpSpeed;
if (Right)
moveDirection.x = jumpSpeed;
if (SwipeManager.IsSwipingLeft())
{
Left = true;
Right = false;
}
if (SwipeManager.IsSwipingRight())
{
Right = true;
Left = false;
}
Vector3 pos = transform.position;
pos.x = Mathf.Lerp(pos.x, firstLaneXPos + laneDistance * laneNumber, Time.deltaTime * sideSpeed);
transform.position = pos;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}