How to make my stick rotating after bouncing with button long pressed? - unity3d

Basically I want to make bouncing stick and rotate control, with the left-right button.i'm facing an issue that the rotate not good as I expected because it won't follow my button like being affected by something after bouncing,
I'm using 2d physics material with friction = 1 and Bounciness = 0.9797 for perfect bouncing also attached to rigidbody2d.
I don't know, should I attach it on collider?
here my Player control Script:
public Rigidbody2D r2d;
public float vertical;
public float horizontal;
public Joystick joystick;
private void Start() {
r2d = gameObject.GetComponent < Rigidbody2D > ();
joystick = FindObjectOfType < Joystick > ();
}
private void Update() {
Movement();
}
public void Movement() {
r2d.velocity = r2d.velocity.normalized * 7f;
//horizontal = joystick.Horizontal;
//vertical = joystick.Vertical;
//if (horizontal == 0 && vertical == 0)
//{
// Vector3 curRot = transform.localEulerAngles;
// Vector3 homeRot = transform.localEulerAngles;
// transform.localEulerAngles = Vector3.Slerp(curRot, homeRot, Time.deltaTime * 2);
//}
//else
//{
// transform.localEulerAngles = new Vector3(0f, 0f, Mathf.Atan2(horizontal, vertical) * -180 / Mathf.PI);
//}
}
public Vector3 target;
public float rotationSpeed = 10f;
public float offset = 5;
public void turnLeft() {
Vector3 dir = target - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(new Vector3(0, 0, angle + offset));
transform.rotation = Quaternion.Slerp(transform.rotation, -rotation, rotationSpeed * Time.deltaTime);
}
public void turnRight() {
Vector3 dir = target - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(new Vector3(0, 0, angle + offset));
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}

Whenever there is a Rigidbody/Rigidbody2D involved you do not want to manipulate anything via the .transform component!
This breaks the physics, collision detection and leads to strange movements basically the transform "fighting" against physics for priority.
What you rather want to do would be e.g. adjusting the Rigidbody2D.angularVelocity
public void turnLeft()
{
// Note that Time.deltaTime only makes sense if this is actually called every frame!
r2d.angularVelocity -= rotationSpeed * Time.deltaTime;
}
public void turnRight()
{
r2d.angularVelocity += rotationSpeed * Time.deltaTime;
}

Related

When jumping, the rotation value becomes 0

this is my PlayerMovement script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
public float Speed = 10f;
private Vector3 moveDirection;
public float groundDistance = 0.4f;
public float gravity = -9.81f;
public float jumpPower = 3.5f;
public float directionY;
bool isGrounded;
public Animator anim;
public Transform cam;
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
moveDirection = new Vector3(horizontal, 0f, vertical).normalized;
if (controller.isGrounded)
{
if (Input.GetKeyDown(KeyCode.Space))
{
directionY = jumpPower;
}
else
{
directionY = 0;
}
}
if (!controller.isGrounded)
{
directionY += gravity * Time.deltaTime;
}
moveDirection.y = directionY;
if (moveDirection.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(moveDirection.x, moveDirection.z) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
controller.Move(moveDirection * Speed * Time.deltaTime);
}
bool hasHorizontalInput = !Mathf.Approximately(horizontal, 0f);
bool hasVerticalInput = !Mathf.Approximately(vertical, 0f);
bool isWalking = hasHorizontalInput || hasVerticalInput;
}
}
I want to make smooth jump system using by characterController.
My code works fine in the ground state, but when I press space(for jump), it returns the current rotation y value to 0.
(I think this problem is because the jump's position value is y, but the movement's rotation value is also y.)
how do i solve it? I want the rotation value not to change even if I jump.
I solved.
It was a code execution order issue.
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (controller.isGrounded && Input.GetButton("Jump"))
{
movingDirection.y = jumpSpeed;
}
movingDirection.y -= gravity * Time.deltaTime;
controller.Move(movingDirection * Time.deltaTime * speed);
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
controller.Move(direction * speed * Time.deltaTime);
}

Dashing in Unity 3D using Rigidbody

im currently making a fps game and i have a rigidbody character controller and im trying to make it dash towards the direction the player is facing however my current dash function makes it go downwards and goes very fast
any ideas for how i can either fix the dashing or make a new dash mechanism?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
float yaw = 0f, pitch = 0f;
Rigidbody rb;
public float walkSpeed = 5f, sensitivity = 2f;
bool jumping = false;
private float DashDistance = 5f;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
rb = GetComponent<Rigidbody>();
}
private void Update()
{
if (Input.GetKey(KeyCode.Space) && Physics.Raycast(rb.transform.position, Vector3.down, 1 + 0.001f))
rb.velocity = new Vector3(rb.velocity.x, 5f, rb.velocity.z);
if (Physics.Raycast(rb.transform.position, Vector3.down, 1 + 0.001f))
jumping = false;
else
jumping = true;
if (jumping && Input.GetKey(KeyCode.LeftControl))
Dash();
Look();
}
private void FixedUpdate()
{
Movement();
}
void Look()
{
pitch -= Input.GetAxisRaw("Mouse Y") * sensitivity;
pitch = Mathf.Clamp(pitch, -90f, 90f);
yaw += Input.GetAxisRaw("Mouse X") * sensitivity;
Camera.main.transform.localRotation = Quaternion.Euler(pitch, yaw, 0f);
}
void Movement()
{
Vector2 axis = new Vector2(Input.GetAxis("Vertical"), Input.GetAxis("Horizontal")) * walkSpeed;
Vector3 forward = new Vector3(-Camera.main.transform.right.z, 0f, Camera.main.transform.right.x);
Vector3 wishDir = (forward * axis.x + Camera.main.transform.right * axis.y + Vector3.up * rb.velocity.y);
rb.velocity = wishDir;
}
void Dash()
{
Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 1f, Input.GetAxis("Vertical"));
Vector3 offset = new Vector3(movement.x * transform.position.x, movement.y * transform.position.y, movement.z * transform.position.z);
rb.AddForce(transform.position + (offset * DashDistance), ForceMode.VelocityChange);
}
}
I think you should add force in the forward direction.
AddForce(transform.forward * yourForceValue);

I wrote a script for movement and mouse look, movement works but mouse look does not

I am writing a script for movement and mouselook, the movement works but the mouse look does not. I start the game, the cursor locks into the game screen and I can move but I can't look around and there are no bugs. can someone help?
Here is my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Controller : MonoBehaviour
{
[SerializeField]private float _speed = 7f;
[SerializeField]private float _mouseSensitivity = 50f;
[SerializeField]private float _minCameraview = -70f, _maxCameraview = 80f;
private CharacterController _charController;
private Camera _camera;
private float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
_charController = GetComponent<CharacterController>();
_camera = Camera.main;
if(_charController == null)
Debug.Log("No Character Controller Attached to Player");
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
//Get WASD Input for Player
float vertical = Input.GetAxis("Vertical");
float horizontal = Input.GetAxis("Horizontal");
//move player based on WASD Input
Vector3 movement = Vector3.forward * vertical + Vector3.right * horizontal;
_charController.Move(movement * Time.deltaTime * _speed);
//Get Mouse position Input
float mouseX = Input.GetAxis("Mouse X") * _mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * _mouseSensitivity * Time.deltaTime;
//Rotate the camera based on the Y input of the mouse
xRotation -= mouseY;
//clamp the camera rotation between 80 and -70 degrees
xRotation = Mathf.Clamp(xRotation, _minCameraview, _maxCameraview);
_camera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
//Rotate the player based on the X input of the mouse
transform.Rotate(Vector3.up * mouseX * 3);
}
}
The problem is that you are multiplying the mouse input by Time.deltaTime. Time.deltaTime is used when you want to have different devices with different frame rates. This is because when multiplying by Time.deltaTime, you get a constant speed of one unit per second:
float speed = 10f;
float movement = speed * Time.deltaTime;
If you have a frame rate of 10fps (hopefully you don't), you would have each frame in 0.1 second. Each frame is 0.1 second, so when multiplying it by 10 (the speed), you get a value of one. If you speed the frame rate up, you would also get 10 units a second (1 x 10 = 10).
The mouse movement doesn’t need this because mouse movement is not handled by the computer. In other words, when you are moving the mouse, it isn’t changing by the frame rate, so you don’t need ‘Time.deltaTime`.
I also noticed that your movement was based on Vector3. What I mean by this is that you were using global coordinates rather than local (transform). This means if the play rotates, Vector3.forward will be different than the player’s forward. You should use transform.forward instead to use local coordinates.
You should change the script to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Controller : MonoBehaviour
{
[SerializeField]private float _speed = 7f;
[SerializeField]private float _mouseSensitivity = 50f;
[SerializeField]private float _minCameraview = -70f, _maxCameraview = 80f;
private CharacterController _charController;
private Camera _camera;
private float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
_charController = GetComponent<CharacterController>();
_camera = Camera.main;
if(_charController == null)
Debug.Log("No Character Controller Attached to Player");
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
//Get WASD Input for Player
float vertical = Input.GetAxis("Vertical");
float horizontal = Input.GetAxis("Horizontal");
//move player based on WASD Input
Vector3 movement = transform.forward * vertical + transform.right * horizontal; //changed this line.
_charController.Move(movement * Time.deltaTime * _speed);
//Get Mouse position Input
float mouseX = Input.GetAxis("Mouse X") * _mouseSensitivity; //changed this line.
float mouseY = Input.GetAxis("Mouse Y") * _mouseSensitivity; //changed this line.
//Rotate the camera based on the Y input of the mouse
xRotation -= mouseY;
//clamp the camera rotation between 80 and -70 degrees
xRotation = Mathf.Clamp(xRotation, _minCameraview, _maxCameraview);
_camera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
//Rotate the player based on the X input of the mouse
transform.Rotate(Vector3.up * mouseX * 3);
}
}
This is a script for both movement and looking
[RequireComponent(typeof(CharacterController))]
public class NewBehaviourScript : MonoBehaviour
{
public float walkingSpeed = 7.5f;
public float runningSpeed = 11.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Camera playerCamera;
public float lookSpeed = 2.0f;
public float lookXLimit = 45.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
float rotationX = 0;
[HideInInspector]
public bool canMove = true;
// Start is called before the first frame update
void Start()
{
characterController = GetComponent<CharacterController>();
// Lock cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// Update is called once per frame
void Update()
{
// We are grounded, so recalculate move direction based on axes
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
// Press Left Shift to run
bool isRunning = Input.GetKey(KeyCode.LeftShift);
float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
float movementDirectionY = moveDirection.y;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
{
moveDirection.y = jumpSpeed;
}
else
{
moveDirection.y = movementDirectionY;
}
// Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
// when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
// as an acceleration (ms^-2)
if (!characterController.isGrounded)
{
moveDirection.y -= gravity * Time.deltaTime;
}
// Move the controller
characterController.Move(moveDirection * Time.deltaTime);
// Player and Camera rotation
if (canMove)
{
rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
}

CharacterController jump in unity

Hello I was trying to do movement script in Unity. Also I wanted to add jump, but everytime when I jump it moves up for like 0.025 on Y direction and stops the player in air*(if I am on 0 and I jump it moves on 0.02545 then 0.0543 etc...)* and I can spam Space to move player up. I added gravity but it looks it doesn't work.. I don't know how to fix it. I hope someone can help me with my problem...
Here is the function what I am using...
Vector3 moveDirection = Vector3.zero;
public float walkingSpeed = 10.0f;
public bool canJump = true;
public float jumpSpeed = 8.0f;
public float gravity = 10.0f;
CharacterController characterController;
void Movement()
{
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
float moveX = walkingSpeed * Input.GetAxis("Vertical");
float moveY = walkingSpeed * Input.GetAxis("Horizontal");
float MovementY = moveDirection.y;
moveDirection = (forward * moveX) + (right * moveY);
if (Input.GetButtonDown("Jump") && canJump)
{
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * Time.deltaTime);
}
Because you are resetting moveDirection every frame (when you call moveDirection = (forward * moveX) + (right * moveY) you aren't letting the gravity accumulate. You should instead save the vertical speed separately and add it every frame.
Something like the following:
Vector3 moveDirection = Vector3.zero;
public float walkingSpeed = 10.0f;
public bool canJump = true;
public float jumpSpeed = 8.0f;
public float gravity = 10.0f;
CharacterController characterController;
private float verticalSpeed;
void Movement()
{
float moveX = walkingSpeed * Input.GetAxis("Vertical");
float moveY = walkingSpeed * Input.GetAxis("Horizontal");
verticalSpeed -= gravity * Time.deltaTime;
if (Input.GetButtonDown("Jump") && canJump)
{
verticalSpeed = jumpSpeed;
}
characterController.Move((moveX * transform.forward + moveY * transform.right + verticalSpeed * transform.up)
* Time.deltaTime);
}
transform.forward is equivalent to transform.TransformDirection(Vector3.forward)

Unity Player floating down instead of falling

for some reason my Player is reacting really weirdly to the gravity, he falls normally for about 1 second then just floats down the rest of the way really slowly. increasing the gravity doesnt change anything either. Im at a loss.
Any help would be greatly appreciated!
using UnityEngine;
public class newThirdPersonMovement : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6;
public float gravity = -20f;
public float jumpHeight = 1;
Vector3 velocity;
bool isGrounded;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
float turnSmoothVelocity;
public float turnSmoothTime = 0.1f;
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}