My Project is a First Person Jump&Run, I want my Player to Sprint by pressing Horizonzal or Vertical combined with Shift.
I already made a new Input, called Sprint, with negative Button "left shift"
My Player does normal move, but he doesn't Sprint.
Thanks a lot.
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float sprint;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y < 0) {
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
// Noch nicht fertig -> Noch ausstehend
if (Input.GetButtonDown("Horizontal") && Input.GetButtonDown("Sprint") || Input.GetButtonDown("Vertical") && Input.GetButtonDown("Sprint"))
{
controller.Move(move * (speed + sprint) * Time.deltaTime);
}
}
There are most likely problems with how the Input is being handled.
My assumption is that GetButtonDown only returns true for the single frame when you press shift down. Use GetKey instead:
Input.GetKey(KeyCode.LeftShift)
If that doesn't work, try those 2 instead:
Input.GetKeyDown("left shift")
Input.GetKeyDown(KeyCode.LeftShift)
But there might be the same problem with those 2 as with "GetButtonDown".
Also, I think it'd help people understand your code better if you use english comments instead of german. I'm able to read it but most probably don't. Don't worry though, that also happened to me!
Related
I'm trying to use the Character Controller component in Unity and I managed to make the movement code, however, I was unable to add jumping and gravity or at least have them work together so my temporary solution was to just break them into 2 different methods. This probably isn't ideal so how could I get this to work properly?
void Update()
{
GetInput();
JumpingCode();
MovementCode();
}
void JumpingCode()
{
// Jumping
if (jumpPressed && characterController.isGrounded)
velocityY = Mathf.Sqrt(jumpHeight * -2f * (gravity * gravityScale));
// Gravity
velocityY += gravity * gravityScale * Time.deltaTime;
Vector3 direction = new Vector3(horizontalInput, velocityY, verticalInput).normalized;
characterController.Move(direction * walkSpeed * Time.deltaTime);
}
void MovementCode()
{
Vector3 direction = new Vector3(horizontalInput, 0f, verticalInput).normalized;
if (direction.magnitude > 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + playerCamera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
Vector3 moveDirection = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
transform.rotation = Quaternion.Euler(0f, angle, 0f);
characterController.Move(moveDirection.normalized * walkSpeed * Time.deltaTime);
}
}
I can't understand how you're arriving at the values you're using there, but the solution would be to accumulate the outputs and then do the .Move() action once at the end, like:
void Update()
{
Vector3 motion;
GetInput();
motion += JumpingCode();
motion += MovementCode();
characterController.Move(motion*Time.deltaTime);
}
private Vector3 JumpingCode()
{
// stuff
return direction * walkSpeed;
}
private Vector3 MovementCode()
{
// stuff
return direction * walkSpeed;
}
Noteworthy there is that I dropped Time.deltaTime from your functions, but I don't know how you were using it in the code you provided.
I use the First Person Character Controller Script from Brackeys. But sometimes, my character walks backwards with no button pressed. I've tried to change the values of the Character Controller and to change the values of the axis in the Project Settings, but nothing really helped.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementScript : MonoBehaviour
{
public CharacterController controller;
public Transform groundcheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpheight = 3f;
Vector3 velocity;
bool isGrounded;
void Start()
{
}
void Update()
{
isGrounded = Physics.CheckSphere(groundcheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y += Mathf.Sqrt(jumpheight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
I really dont know what the problem is, but maybe you can help me
I see nothing wrong with the script. Something must be giving a vertical input outside the script.
If you're using a controller, your left joystick might have some drift issues. Adding some deadzone to your movement vector can prevent any involuntary movement from happening. For example, you can check if your input is inferior to a certain threshold and set it to zero if that's the case.
Here's a simple way to do it (in this example, the threshold is 0.125. If the joystick drift still gives an input, try an higher value.):
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
if(x <= 0.125f)
x = 0
if(y <= 0.125f)
y = 0
Little late here but I had the same issue.
What caused it was having another controller plugged in besides mouse and keyboard, in my case a steering wheel. So make sure all extra controllers are unplugged
I have a problem with blend tree which I'm using it and a script to change the float so I can control the player's animation. But the value of the parameter in the blend tree went crazy when it return to 0. It start appearing random numbers and the only way I know to fix it is to reset it manually.
This is what happen after hitting 0 -->
what happen.gif
Is it there way I use the blend tree wrong or a new bug in unity?. Any ideas??
AnimationController
animationController.jpg
ThirdPersonCharacterController
public float walkSpeed = 2;
public float runSpeed = 6;
public float gravity = -12;
public float jumpHeight = 1;
public float airControlPercent;
public float turnSmoothTime = 0.2f;
float turnSmoothVelocity;
public float speedSmoothTime = 0.1f;
float speedSmoothVelocity;
float currentSpeed;
float velocityY;
Animator animator;
Transform cameraT;
CharacterController controller;
void Start () {
animator = GetComponent<Animator> ();
cameraT = Camera.main.transform;
controller = GetComponent<CharacterController> ();
}
void Update () {
// input
Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical"));
Vector2 inputDir = input.normalized;
bool running = Input.GetKey (KeyCode.LeftShift);
Move (inputDir, running);
if (Input.GetKeyDown (KeyCode.Space)) {
Jump ();
}
// animator
float animationSpeedPercent = ((running) ? currentSpeed / runSpeed : currentSpeed / walkSpeed * .5f);
animator.SetFloat ("speedPercent", animationSpeedPercent, speedSmoothTime, Time.deltaTime);
}
void Move(Vector2 inputDir, bool running) {
if (inputDir != Vector2.zero) {
float targetRotation = Mathf.Atan2 (inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraT.eulerAngles.y;
transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
}
float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
currentSpeed = Mathf.SmoothDamp (currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
velocityY += Time.deltaTime * gravity;
Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;
controller.Move (velocity * Time.deltaTime);
currentSpeed = new Vector2 (controller.velocity.x, controller.velocity.z).magnitude;
if (controller.isGrounded) {
velocityY = 0;
}
}
void Jump() {
if (controller.isGrounded) {
float jumpVelocity = Mathf.Sqrt (-2 * gravity * jumpHeight);
velocityY = jumpVelocity;
}
}
float GetModifiedSmoothTime(float smoothTime) {
if (controller.isGrounded) {
return smoothTime;
}
if (airControlPercent == 0) {
return float.MaxValue;
}
return smoothTime / airControlPercent;
}
Note: the parameter for the blend tree is "speedPercent"
I am not sure but i think that the value you are seeing is so near to zero that it has gone to exponential form as Unity always does for smaller values like
And this is because you are using smooth transition for SetFloat
animator.SetFloat ("speedPercent", animationSpeedPercent,
speedSmoothTime, Time.deltaTime);
Try this
animator.SetFloat ("speedPercent", animationSpeedPercent);
friends, new dev asking, I looked through a lot of sites and tried a lot of different scripts separate scripts from player movement and other scripts to no avail and came up with this as a conglomeration of what I've seen but it also doesn't work, at all. I couldn't find anything in subreddits or this. I know my normal movement code is probably ugly but it works. I hope you can help thank you!
TO clarify this is making the player sprint while holding down the shift key thank you for those who reminded me to elaborate.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(UnityEngine.AI.NavMeshAgent))]
public class PlayerMovement : MonoBehaviour
{
UnityEngine.AI.NavMeshAgent agent;
private Rigidbody rb;
public float movementSpeed = 5.0f;
public float clockwise = 1000.0f;
public float counterClockwise = -5.0f;
public float Speed = 5.0f;
public Vector3 jump;
public float jumpForce =1.0f;
public float shiftSpeed = 10.0f;
public bool isGrounded;
void Start()
{
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 1.0f, 0.0f);
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}
void OnCollisionStay()
{
isGrounded = true;
}
void Update()
{
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.position += transform.forward \* Time.deltaTime \* movementSpeed;
}
else if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftShift))
{
transform.position += transform.forward \* Time.deltaTime \* shiftSpeed;
}
else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.position -= transform.forward \* Time.deltaTime \* movementSpeed;
}
else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow) && Input.GetKey(KeyCode.LeftShift))
{
transform.position += transform.forward \* Time.deltaTime \* shiftSpeed;
}
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
GetComponent<Rigidbody>().position += Vector3.left \* Time.deltaTime \* movementSpeed;
}
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow) && Input.GetKey(KeyCode.LeftShift))
{
transform.position += transform.forward \* Time.deltaTime \* shiftSpeed;
}
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
GetComponent<Rigidbody>().position += Vector3.right \* Time.deltaTime \* movementSpeed;
}
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow) && Input.GetKey(KeyCode.LeftShift))
{
transform.position += transform.forward \* Time.deltaTime \* shiftSpeed;
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(jump \* jumpForce, ForceMode.Impulse);
isGrounded = false;
}
}
}
I assume what you are asking is "How to make my player move faster when I hold down the shift key?"
I would suggest having two constants for walking speed and running speed. Then another variable that changes based on if the shift key is held:
private const float walkSpeed = 5.0f;
private const float runSpeed = 10.0f;
private float moveSpeed = walkSpeed; // Our current movement speed
//...
void Update() {
//...
if (Input.GetKey(KeyCode.LeftShift) {
// Set current speed to run if shift is down
moveSpeed = runSpeed;
}
else {
// Otherwise set current speed to walking speed
moveSpeed = walkSpeed;
}
}
I'm having a bit of an issue with a BoxCollider2D I have on my GameObject. When I rotate the GameObject, the BoxCollider2D rotates with it, but not as fast. Is there a way to get the BoxCollider2D to move at the same rate as the GameObject? I feel like I'm missing something obvious.
Before Rotation
After Rotation
Below is my code for the movement of the player:
Animator anim;
Rigidbody2D rbody;
float speed = 0f;
public float moveSpeed = 0.6f;
public float acceleration = 0.2f;
public int turnSpeed = 20;
bool sails = false;
// Use this for initialization
void Start () {
anim = GetComponentInChildren<Animator> ();
rbody = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void Update () {
if (sails) {
rbody.transform.Translate (transform.right * (speed * Time.deltaTime));
speed += acceleration * Time.deltaTime;
if (speed > moveSpeed)
speed = moveSpeed;
if (Input.GetKey (KeyCode.LeftArrow)) {
rbody.transform.Rotate (0,0,turnSpeed * Time.deltaTime);
}
if (Input.GetKey (KeyCode.RightArrow)) {
rbody.transform.Rotate (0,0,-turnSpeed * Time.deltaTime);
}
}
if (!sails) {
rbody.transform.Translate (transform.right * (speed * Time.deltaTime));
speed += -acceleration * Time.deltaTime;
if (speed < 0f)
speed = 0f;
}
if (Input.GetKeyDown (KeyCode.Space)) {
sails = !sails;
anim.SetBool ("sailsDown", sails);
}
}
The problem is not your rotation, but how you are applying the the movement.
You are using transform.right which is the local right of the object. But then, when applying the translate you apply it to the object locally too.
For example, if your ship is facing down (rotation.Z = -90), transform.right value is (0,-1,0), in World coordinates this is equal to "down".
But then you use rbody.transform.Translate(vector) which will translate the object using local coordinates. This means that if you pass it the "down" vector, it will be moving down locally, which in the case of being rotated -90 inthe Z axis, means moving "left" relative to the world.
You have to change this line:
rbody.transform.Translate(transform.right * (speed * Time.deltaTime));
To:
rbody.transform.Translate(transform.right * (speed * Time.deltaTime),Space.World);
Or:
rbody.transform.Translate(Vector2.right * (speed * Time.deltaTime));