Making Player Movement Less Floaty - c#

So I am having issues with my runner game.
At the moment the movement feels way to icy because I have momentum, I have to stop going one way to go the other and it gives me this really icy effect I don't want.
I have tried upping friction but that results in my cube tumbling down the track
void FixedUpdate()
{
rb.AddForce(0, 0, forwardForce * Time.deltaTime);
if (Input.GetKey("d"))
{
rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
if (Input.GetKey("a"))
{
rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
I want the movement to be nice and smooth and snappy.

So, first of all: I would recommend not using AddForce for movement of the player, you can just rb.velocity = sth; (that would remove the icy).
But! If you really want it that way, I guess you could try:
rb.AddForce(-rb.velocity*(from 0 to 1 the less the less icy) + (the speed you want to change to));
I think this would work. Try it, but also, if it's a capsule collider, you could loon at the Character Controller that makes it all look better and simpler, or at the Rigidbody Controller (not a component, just a name to define what you are trying but with the rb.velocity method).
Hope it works!

maybe this:
Vector3 CalculatedForce = -rb.velocity;
CalculatedForce.z = forwardForce * Time.deltaTime;
if (Input.GetKey("d"))
CalculatedForce.x += sidewaysForce * Time.deltaTime;
else if (Input.GetKey("a"))
CalculatedForce.x += -sidewaysForce * Time.deltaTime;
rb.AddForce(CalculatedForce, ForceMode.VelocityChange);

Related

Unity: player moves up without any such code

I'm creating a movement function for my character(which I've done many times but this time it's not working correctly) and here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
[RequireComponent(typeof(Animator))]
public class Movement : MonoBehaviour {
public CharacterController controller;
public float moveSpeed;
public float jumpForce;
public float gravityScale;
public Animator animator;
private bool shiftPressed = false;
private void Update()
{
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
shiftPressed = true;
else
shiftPressed = false;
if(shiftPressed)
{
moveSpeed = 20f;
} else
{
moveSpeed = 10f;
}
Vector3 moveDirection = new Vector3(Input.GetAxisRaw("Horizontal") * moveSpeed, 0.0f, Input.GetAxis("Vertical") * moveSpeed);
if(Input.GetKey(KeyCode.Space) && controller.isGrounded)
{
moveDirection.y = jumpForce;
}
if (moveDirection != Vector3.zero)
animator.SetFloat("Speed", moveSpeed);
else if (moveDirection == Vector3.zero)
animator.SetFloat("Speed", 0f);
else if (moveDirection != Vector3.zero)
animator.SetFloat("Speed", moveSpeed);
if(moveDirection != Vector3.zero)
transform.rotation = Quaternion.LookRotation(moveDirection);
moveDirection = Camera.main.transform.TransformDirection(moveDirection);
moveDirection.y = moveDirection.y + (Physics.gravity.y * Time.deltaTime * gravityScale);
controller.Move(moveDirection * Time.deltaTime);
}
}
As you can see that there is no function to go up in the y axis except the jump function. Mysteriously, when I press the 'S' key or 'downArrow' the player moves -z as he should but ironically he moves in +y axis as well. To ensure there is no y axis function I tried making jump function a comment but did the same way still. I thought it might be some character specific problem so I tried adding the code to a cube(thinking it to be my animation mistake) but it didn't helped at any point. I ensured the character controller is set nicely(collider and stuff); I've attached screenshots.
Please help!
Thanks in advance.
The problem has already been stated by several here, but it seems you still do not understand the issue, concluding from your reactions.
This line will always make your character move up.
moveDirection.y = moveDirection.y + (Physics.gravity.y * Time.deltaTime * gravityScale);
You are trying to use gravity (which is a force) in conjunction with manipulating transform. In Unity, you either do one of the two, not both. This will lead to undesired and hard to fix results.
If you want to use forces in your code, then i suggest the follow:
Add a RigidBody to your character. Check the "use gravity" checkbox.
Get the RigidBody in your controller script by calling and add force to it to move it.
var rb = getComponent<RigidBody>();
rb.AddForce(10f);
Do note that if you add force, you can add it continuosly in the Update method, or just once by passing a second paramater "forcemode".
rb.AddForce(10, ForceMode.Impulse); // add instant force, using mass
// Or
rb.AddForce(10, ForceMode.VelocityChange); // add instant force, ignoring mass
// Or
rb.AddForce(10, ForceMode.Force); // add continuous force, using mass
// Or
rb.AddForce(10, ForceMode.Acceleration); // add continous force, ignoring mass
Let me guess.. your character keeps moving up by about the current downwards slope of the camera?
As your code stands, as an example, if your Camera's is Vector3(10,0,0) and if you're trying to move Vector3(5, 0, 5), you've asked the movement vector to be transformed to world space, based off of the camera transform. So, your new movement vector will be something like Vector3(5,1,5). This should do the trick:
var worldDirection = Camera.main.transform.TransformDirection(moveDirection);
moveDirection = new Vector3(
worldDirection.x,
moveDirection.y + (Physics.gravity.y * Time.deltaTime * gravityScale),
worldDirection.z );
moveDirection.y = moveDirection.y + (Physics.gravity.y * Time.deltaTime * gravityScale);
This line always sets "y", and is modified/set as the last function prior to the ultimate statement. It is here, you should validate and verify all factors that has influence the final calculation of "y".
You must validate that each of the variables are calculated to your expected values:
moveDirection.y
Physics.gravity.y
Time.deltaTime
gravityScale
Each will influence the final value of moveDirection.y. Once you have verified each individual value, the final y value will make sense to you. If any of these values are not what you expect, you have a bug in the calculation of that variable.
Happy hunting!

How to Reference the "SpaceBar" Key in C# (Unity)?

In Unity, how do I reference the SpaceBar Key in order to apply force to an object when Space Bar is pressed?
void Update()
{
rb.AddForce(0, 0, forwardforce * Time.deltaTime);
if (Input.GetKey("a"))
{
rb.AddForce(500 * Time.deltaTime, 0, 0);
}
if (Input.GetKey("w"))
{
rb.AddForce(0, 0, -500 * Time.deltaTime);
}
if (Input.GetKey("s"))
{
rb.AddForce(0, 0, 500 * Time.deltaTime);
}
if (Input.GetKey("d"))
{
rb.AddForce(-500 * Time.deltaTime, 0, 0);
}
if (Input.GetKey("vbKeySpace"))
{
rb.AddForce(0, 300 * Time.deltaTime, 0);
}
}
You could try the following:
Input.GetKey("space");
Or, using the KeyCode enumeration:
Input.GetKey(KeyCode.Space);
See the docs on this enumeration here.
Input.GetKey operates on the string-names of the Conventional Game Input key list.
Special keys: “backspace”, “tab”, “return”, “escape”, “space”, “delete”, “enter”, “insert”, “home”, “end”, “page up”, “page down”
However, I recommend looking into Input.GetButton instead. This allows the player to rebind the keys to something more suitable for them, rather than being forced to use WASD and Space.
So you would instead use Input.GetButton("Jump") and define in Edit -> Project Settings -> Input that "Jump" is mapped to the positive key "space" (Unity will auto-supply some default keys, and Jump:Space is one).
Additionally you can switch your Input.GetKey("a")/Input.GetKey("d") with Input.GetAxis("Horizontal").

Player object changes position while rotating

First of all: Sorry for my bad English, I'm Dutch.
I'm trying to create a player object that can walk forward and backwards (with the up and down keys), and rotate the player with the right and left keys. But when I press the left or right key, the position of the player changes, it looks like it rotates around a certain point. But it should rotate and stay on the same place, like I do when I turn around.
I have some other small programs, with the same 'move script' and the same inputmanager settings. There it works fine, so I have no idea why it doesn't work this time.
This is my move script, but this script works fine with other programs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour
{
public float speed = 3f;
public float rotate = 50f;
private Rigidbody rb;
// Update is called once per frame
private void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetButton("Up"))
transform.Translate(Vector3.forward * speed * Time.deltaTime);
if (Input.GetButton("Down"))
transform.Translate(-Vector3.forward * speed * Time.deltaTime);
if (Input.GetButton("Right"))
transform.Rotate(Vector3.up, rotate * Time.deltaTime);
if (Input.GetButton("Left"))
transform.Rotate(-Vector3.up, rotate * Time.deltaTime);
if (gameObject.GetComponent<Rigidbody>().velocity.y < 0.01)
{
if (Input.GetButtonDown("Jump"))
rb.AddForce(0, 225, 0);
}
}
}
The InputManager settings (also the same as other programs where it works fine):
If someone wants a screenshot of something else of my program, you can always ask it of course. I have no idea what the problem could be, if it isn't in the script or the inputmanager.
Following the comments in the OP, the solution should be to use:
if (Input.GetButton("Right"))
transform.localEulerAngles = transform.localEulerAngles + new Vector3(xRotation, 0, 0) * Time.deltaTime;
if (Input.GetButton("Left"))
transform.localEulerAngles = transform.localEulerAngles - new Vector3(xRotation, 0, 0) * Time.deltaTime;
Where xRotation is a float with the amount you want to rotate per second when and while one of the rotation keys is down.
(PS: Don't have unity open right now, so + and - might be inverted, but should be something like that.)

moving a rigidbody left and right

I can't seem to get my rigidbody to move left and right. The code looks fine and very similar to what everyone else has posted!
The debug statement is getting called but my character is not moving left and right.
Thanks for the help.
public float speed = 4.0f;
void Update()
{
float moveDirection = Input.GetAxis("Horizontal");
if (Input.GetKeyDown("d"))
{
Debug.Log("pressed d");
rb.AddForce(new Vector2(Time.deltaTime * speed * moveDirection, 0), ForceMode2D.Force);
}
I just tested it using an 3D environment, but that shouldn't matter. So after all I'm pretty sure you've got way to less force applied to AddForce.
So try increasing speed to about 40000, then you should be able to notice the AddForce being applied.
If you want to keep the speed value low, you could of course just add a multiplier here:
rb.AddForce(new Vector2(Time.deltaTime * speed * moveDirection * 10000f, 0), ForceMode2D.Force);
A nice one line option would be to use transform translate.
void Update ()
{
transform.Translate(Vector3.right * speed * Input.GetAxis("Horizontal") * Time.deltaTime);
}
AddForce will not work on a Rigidbody which is kinematic. Verify and set isKinematic to false in your Rigidbody component.
If this is already false, trying increasing the force value as suggested by d4Rk.

Move a GameObject from point A to point B - Unity3D

for the game I 'm creating I was trying to create a mega start that take you 750 meters ahead, but when trying to do this with vector3.lerp this is done instantly , and after trying many things he could not get it to work.
Here is the script that i wrote
if (in750Run)
{
PlayerManager.Instanse.gameObject.transform.position = Vector3.Lerp(PlayerManager.Instanse.gameObject.transform.position,PowerUpFinalePlayer.position, Time.deltaTime * 5);
Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position, PowerUpFinaleCamera.position, Time.deltaTime * 5);
if (Vector3.Distance(PlayerManager.Instanse.gameObject.transform.position, PowerUpFinalePlayer.position) > 2)
{
in750Run = false;
}
}
If you have a better way of doing this, please replay to this post :)
1) If you need smooth rotate to the target use:
Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed*Time.deltaTime);
2) To set a speed:
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;

Categories