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);
}
}
Related
I'm trying to make a First Person Controller and after I jump, right as the player is about to hit the ground, it jumps a second time by itself. This doesn't seem to be the case when the player lands on ground higher or lower than the ground it originally jumped on.
This is my Player code:
`
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
[SerializeField] float mouseSensitivity = 3f;
[SerializeField] float walkingSpeed = 10f;
[SerializeField] float flyingSpeed = 15;
[SerializeField] float climbingSpeed = 5f;
[SerializeField] float mass = 1f;
[SerializeField] float acceleration = 20f;
[SerializeField] float worldBottomBoundary = -100f;
public Transform cameraTransform;
public bool IsGrounded => controller.isGrounded;
public float Height
{
get => controller.height;
set => controller.height = value;
}
public event Action OnBeforeMove;
public event Action<bool> OnGroundStateChange;
internal float movementSpeedMultiplier;
State _state;
public State CurrentState
{
get => _state;
set
{
_state = value;
velocity = Vector3.zero;
}
}
public enum State
{
Walking,
Flying,
Climbing
}
CharacterController controller;
internal Vector3 velocity;
Vector2 look;
(Vector3, Quaternion) initialPositionAndRotation;
bool wasGrounded;
PlayerInput playerInput;
InputAction moveAction;
InputAction lookAction;
InputAction flyUpDownAction;
void Awake()
{
controller = GetComponent<CharacterController>();
playerInput = GetComponent<PlayerInput>();
moveAction = playerInput.actions["move"];
lookAction = playerInput.actions["look"];
flyUpDownAction = playerInput.actions["flyUpDown"];
}
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
initialPositionAndRotation = (transform.position, transform.rotation);
}
public void Teleport(Vector3 position, Quaternion rotation)
{
transform.position = position;
Physics.SyncTransforms();
look.x = rotation.eulerAngles.y;
look.y = rotation.eulerAngles.z;
velocity = Vector3.zero;
}
void Update()
{
movementSpeedMultiplier = 1f;
switch (CurrentState)
{
case State.Walking:
UpdateGround();
UpdateGravity();
UpdateMovement();
UpdateLook();
CheckBounds();
break;
case State.Flying:
UpdateMovementFlying();
UpdateLook();
break;
case State.Climbing:
UpdateMovementClimbing();
UpdateLook();
break;
}
}
void CheckBounds()
{
if (transform.position.y < worldBottomBoundary)
{
var (position, rotation) = initialPositionAndRotation;
Teleport(position, rotation);
}
}
void UpdateGround()
{
if (wasGrounded != IsGrounded)
{
OnGroundStateChange?.Invoke(IsGrounded);
wasGrounded = IsGrounded;
}
}
void UpdateGravity()
{
var gravity = Physics.gravity * mass * Time.deltaTime;
velocity.y = IsGrounded ? -1f : velocity.y + gravity.y;
}
Vector3 GetMovementInput(float speed, bool horizontal = true)
{
var moveInput = moveAction.ReadValue<Vector2>();
var flyUpDownInput = flyUpDownAction.ReadValue<float>();
var input = new Vector3();
var referenceTransform = horizontal ? transform : cameraTransform;
input += referenceTransform.forward * moveInput.y;
input += referenceTransform.right * moveInput.x;
if (!horizontal)
{
input += transform.up * flyUpDownInput;
}
input = Vector3.ClampMagnitude(input, 1f);
input *= speed * movementSpeedMultiplier;
return input;
}
void UpdateMovement()
{
OnBeforeMove?.Invoke();
var input = GetMovementInput(walkingSpeed);
var factor = acceleration * Time.deltaTime;
velocity.x = Mathf.Lerp(velocity.x, input.x, factor);
velocity.z = Mathf.Lerp(velocity.z, input.z, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateMovementFlying()
{
var input = GetMovementInput(flyingSpeed, false);
var factor = acceleration * Time.deltaTime;
velocity = Vector3.Lerp(velocity, input, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateMovementClimbing()
{
var input = GetMovementInput(climbingSpeed, false);
var forwardInputFactor = Vector3.Dot(transform.forward, input.normalized);
if (forwardInputFactor > 0)
{
input.x = input.x * .5f;
input.z = input.z * .5f;
if (Mathf.Abs(input.y) > .2f)
{
input.y = Mathf.Sign(input.y) * climbingSpeed;
}
}
else
{
input.y = 0;
input.x = input.x * 3f;
input.z = input.z * 3f;
}
var factor = acceleration * Time.deltaTime;
velocity = Vector3.Lerp(velocity, input, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateLook()
{
var lookInput = lookAction.ReadValue<Vector2>();
look.x += lookInput.x * mouseSensitivity;
look.y += lookInput.y * mouseSensitivity;
look.y = Mathf.Clamp(look.y, -90, 90f);
cameraTransform.localRotation = Quaternion.Euler(-look.y, 0, 0);
transform.localRotation = Quaternion.Euler(0, look.x, 0);
}
void OnToggleFlying()
{
CurrentState = CurrentState == State.Flying ? State.Walking : State.Flying;
}
}
`
And this is my PlayerJumping code:
`
using UnityEngine;
[RequireComponent(typeof(Player))]
public class PlayerJumping : MonoBehaviour
{
[SerializeField] float jumpSpeed = 5f;
[SerializeField] float jumpPressBufferTime = .05f;
[SerializeField] float jumpGroundGraceTime = .2f;
[SerializeField] int maxJumps = 1;
Player player;
bool tryingToJump;
float lastJumpPressTime;
float lastGroundedTime;
int jumps;
void Awake()
{
player = GetComponent<Player>();
}
void OnEnable()
{
player.OnBeforeMove += OnBeforeMove;
player.OnGroundStateChange += OnGroundStateChange;
}
void OnDisable()
{
player.OnBeforeMove -= OnBeforeMove;
player.OnGroundStateChange -= OnGroundStateChange;
}
void OnJump()
{
tryingToJump = true;
lastJumpPressTime = Time.time;
}
void OnBeforeMove()
{
if (player.IsGrounded) jumps = 0;
var wasTryingToJump = Time.time - lastJumpPressTime < jumpPressBufferTime;
var wasGrounded = Time.time - lastGroundedTime < jumpGroundGraceTime;
var isOrWasTryingToJump = tryingToJump || (wasTryingToJump && player.IsGrounded);
var isOrWasGrounded = player.IsGrounded || wasGrounded;
var jumpAllowed = jumps < maxJumps;
if (
jumpAllowed && isOrWasTryingToJump && isOrWasGrounded
|| jumpAllowed && tryingToJump
)
{
player.velocity.y += jumpSpeed;
jumps++;
}
tryingToJump = false;
}
void OnGroundStateChange(bool isGrounded)
{
if (!isGrounded) lastGroundedTime = Time.time;
}
}
`
Although to be honest, I've checked a million times and I'm starting to believe the problem isn't in the code but in the inspector, but don't let that cloud your judgement because I can be pretty stupid at times. Do you have any ideas?
after my character goes up a slope or stairs while sprinting it keeps the momentum and usually flies over the platform at the top because hes moving too fast how would i get him to stay on the ground coming out of a slope but still be able to jump
im using a rigid body and heres the script im using to move the character
{
[Header("Movement")]
private float moveSpeed;
public float walkSpeed;
public float sprintSpeed;
public float slideSpeed;
private float desiredMoveSpeed;
private float lastDesiredMoveSpeed;
public float speedIncreaseMultiplier;
public float slopeIncreaseMultiplier;
public float groundDrag;
[Header("Jumping")]
public float jumpForce;
public float jumpCooldown;
public float airMultiplier;
bool readyToJump;
[Header("Crouching")]
public float crouchSpeed;
public float crouchYScale;
private float startYScale;
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
public KeyCode sprintKey = KeyCode.LeftShift;
public KeyCode crouchKey = KeyCode.LeftControl;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
[Header("Slope Handling")]
public float maxSlopeAngle;
private RaycastHit slopeHit;
private bool exitingSlope;
public Rigidbody playerRb;
public Transform orientation;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
crouching,
sliding,
air
}
public bool sliding;
private void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
readyToJump = true;
startYScale = transform.localScale.y;
}
private void Update()
{
// ground check
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
SpeedControl();
StateHandler();
// handle drag
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
// when to jump
if (Input.GetKey(jumpKey) && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
// start crouch
if (Input.GetKeyDown(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, crouchYScale, transform.localScale.z);
rb.AddForce(Vector3.down * 5f, ForceMode.Impulse);
}
// stop crouch
if (Input.GetKeyUp(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, startYScale, transform.localScale.z);
}
}
private void StateHandler()
{
// Mode - Sliding
if (sliding)
{
state = MovementState.sliding;
if (OnSlope() && rb.velocity.y < 0.1f)
desiredMoveSpeed = slideSpeed;
else
desiredMoveSpeed = sprintSpeed;
}
// Mode - Crouching
else if (Input.GetKey(crouchKey))
{
state = MovementState.crouching;
desiredMoveSpeed = crouchSpeed;
}
// Mode - Sprinting
else if (grounded && Input.GetKey(sprintKey))
{
state = MovementState.sprinting;
desiredMoveSpeed = sprintSpeed;
}
// Mode - Walking
else if (grounded)
{
state = MovementState.walking;
desiredMoveSpeed = walkSpeed;
}
// Mode - Air
else
{
state = MovementState.air;
}
// check if desiredMoveSpeed has changed drastically
if (Mathf.Abs(desiredMoveSpeed - lastDesiredMoveSpeed) > 4f && moveSpeed != 0)
{
StopAllCoroutines();
StartCoroutine(SmoothlyLerpMoveSpeed());
}
else
{
moveSpeed = desiredMoveSpeed;
}
lastDesiredMoveSpeed = desiredMoveSpeed;
}
private IEnumerator SmoothlyLerpMoveSpeed()
{
// smoothly lerp movementSpeed to desired value
float time = 0;
float difference = Mathf.Abs(desiredMoveSpeed - moveSpeed);
float startValue = moveSpeed;
while (time < difference)
{
moveSpeed = Mathf.Lerp(startValue, desiredMoveSpeed, time / difference);
if (OnSlope())
{
float slopeAngle = Vector3.Angle(Vector3.up, slopeHit.normal);
float slopeAngleIncrease = 1 + (slopeAngle / 90f);
time += Time.deltaTime * speedIncreaseMultiplier * slopeIncreaseMultiplier * slopeAngleIncrease;
}
else
time += Time.deltaTime * speedIncreaseMultiplier;
yield return null;
}
moveSpeed = desiredMoveSpeed;
}
private void MovePlayer()
{
// calculate movement direction
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
// on slope
if (OnSlope() && !exitingSlope)
{
rb.AddForce(GetSlopeMoveDirection(moveDirection) * moveSpeed * 20f, ForceMode.Force);
if (rb.velocity.y > 0)
rb.AddForce(Vector3.down * 80f, ForceMode.Force);
}
// on ground
else if (grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
// in air
else if (!grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
// turn gravity off while on slope
rb.useGravity = !OnSlope();
}
private void SpeedControl()
{
// limiting speed on slope
if (OnSlope() && !exitingSlope)
{
if (rb.velocity.magnitude > moveSpeed)
rb.velocity = rb.velocity.normalized * moveSpeed;
}
// limiting speed on ground or in air
else
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
// limit velocity if needed
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
}
private void Jump()
{
exitingSlope = true;
// reset y velocity
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void ResetJump()
{
readyToJump = true;
exitingSlope = false;
}
public bool OnSlope()
{
if (Physics.Raycast(transform.position, Vector3.down, out slopeHit, playerHeight * 0.5f + 0.3f))
{
float angle = Vector3.Angle(Vector3.up, slopeHit.normal);
return angle < maxSlopeAngle && angle != 0;
}
return false;
}
public Vector3 GetSlopeMoveDirection(Vector3 direction)
{
return Vector3.ProjectOnPlane(direction, slopeHit.normal).normalized;
}
}```
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
I want to flip my sprites depending on which direction they are going and then stay in that position until they move again. I've tried velocity detection and the flipping the sprites accordingly, but since my movement is not by force but by changing position it can't detect velocity (I think), so any suggestions would be helpful.
Here's the movement script I've got so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
//DRAG AND DROP
bool isBeingDragged = false;
//POSITIONS AND TARGET
public float speed = 0.5f;
float timer = 0f;
public float waitTime;
public float distanceToAchieve = 0.2f;
bool isFollowing = true;
bool isWaiting = false;
//GOAL TARGET
public GameObject goalGameObject;
Vector2 target;
public Vector2 bounds = new Vector2(1.75f, 3);
private Vector2 RP;
private float startPosX;
private float startPosY;
void Start()
{
if (this.gameObject.tag == "1")
{
transform.position = RandomizePosition();
}
target = RandomizePosition();
isFollowing = true;
}
private void Update()
{
if (!isBeingDragged)
{
if (!isWaiting && Vector2.Distance(transform.position, target) < distanceToAchieve)
{
isWaiting = true;
isFollowing = false;
RandomizeGoal();
}
if (isWaiting)
{
timer += Time.deltaTime;
if (timer > waitTime)
{
timer = 0f;
isWaiting = false;
isFollowing = true;
}
}
}
}
private void FixedUpdate()
{
if (isFollowing && !isBeingDragged)
{
transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
if (isBeingDragged)
{
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
this.gameObject.transform.localPosition = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
}
}
Vector2 RandomizePosition()
{
RP = new Vector2(transform.position.x - Random.Range(-1f, 1f), transform.position.y - Random.Range(-1f, 1f));
if (RP.x < bounds.x && RP.x > bounds.x * -1 && RP.y < bounds.y && RP.y > bounds.y * -1)
{
return RP;
}
else
{
return new Vector2(transform.position.x, transform.position.y);
}
}
void RandomizeGoal()
{
waitTime = Random.Range(2, 10);
target = RandomizePosition();
goalGameObject.transform.position = target;
}
private void OnMouseDown()
{
isBeingDragged = true;
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
startPosX = mousePos.x - this.transform.localPosition.x;
startPosY = mousePos.y - this.transform.localPosition.y;
}
private void OnMouseUp()
{
isBeingDragged = false;
GetComponent<Merging>().CheckNearest();
}
}
private void FixedUpdate()
{
if (isFollowing && !isBeingDragged)
{
transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
if (isBeingDragged)
{
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
// capture the current position of target
// by the way, why you use "loclPosition" for moving ??
// I don't thinkg this is appropriate.
var currentPos = this.gameObject.transform.localPosition;
var newPos = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
// then compare this with new position
bool isLeftSided = false;
if (newPos.x > currentPos.x)
{
isLeftSided = true;
}
else
{
isLeftSided = false;
}
// And figure out the direction . in this example, I wrote just right-left case
// use the y pos for up and down
// then flip the sprite ( this case, default is right sided )
this.gameObject.GetComponent<SpriteRenderer>().flipX. = isLeftSided;
this.gameObject.transform.localPosition = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
}
}
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.