I'm having an issue where my gameObject barely jumps at all. I think it has something to do with moveDirection because the jumping works when I comment out p.velocity = moveDirection.
Any suggestions on how to fix this?
using UnityEngine;
using System.Collections;
public class Controller : MonoBehaviour
{
public float jumpHeight = 8f;
public Rigidbody p;
public float speed = 1;
public float runSpeed = 3;
public Vector3 moveDirection = Vector3.zero;
// Use this for initialization
void Start ()
{
p = GetComponent<Rigidbody>();
p.velocity = Vector3.zero;
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown (KeyCode.Space))
{
p.AddForce(new Vector3(0, jumpHeight, 0), ForceMode.Impulse);
}
Move ();
}
void Move ()
{
if(Input.GetKey(KeyCode.D))
{
transform.Rotate(Vector3.up, Mathf.Clamp(180f * Time.deltaTime, 0f, 360f));
}
if(Input.GetKey(KeyCode.A))
{
transform.Rotate(Vector3.up, -Mathf.Clamp(180f * Time.deltaTime, 0f, 360f));
}
moveDirection = new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
if(Input.GetKey(KeyCode.LeftShift))
{
moveDirection *= runSpeed;
}
else
{
moveDirection *= speed;
}
p.velocity = moveDirection;
}
}
Try using a much higher value for your jumpheight variable. I usually go with something in the hundreds.
Because right after doing the AddForce(...) literally within the same frame you override the velocity with moveDirection. You should be adding to the current velocity, instead of overriding it entirely as such:
Vector3 velocity = p.velocity;
p.velocity = velocity + moveDirection;
This is exactly why Unity warns against messing with velocity directly, youd be better off just doing another AddForce(...) for your movement:
p.AddForce(moveDirection * Time.deltaTime);
EDIT:
i don't like digressing too far from the OP's question, but your new problems are probably because you are doing too much with moveDirection half of what i don't even understand why but it should for the most part look like this:
moveDirection = new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical")).normalized;
float _speed = Input.GetKey(KeyCode.LeftShift) ? runspeed : speed;
p.AddForce(moveDirection * _speed * Time.deltaTime);
Okay I figured out how to fix it. Instead of those MoveDirection variables I changed it to
if(Input.GetKey(KeyCode.W)) {
transform.position += transform.forward * Time.deltaTime * speed;
}
if(Input.GetKey(KeyCode.S)) {
transform.position -= transform.forward * Time.deltaTime * speed;
}
and now it works just fine.
Related
i've following issue. I'm trying to make game with top down view (something like first GTA game). The problem is when i press the key my player is moving, but can't stop. Here you can see my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovemenet : MonoBehaviour
{
private Rigidbody2D m_Rigidbody;
private Transform playerTransform;
public float m_Speed = 100.0f;
// Start is called before the first frame update
void Start()
{
m_Rigidbody = GetComponent<Rigidbody2D>();
playerTransform = GameObject.Find("Player").transform;
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 playerPos = playerTransform.eulerAngles;
if (Input.GetKey(KeyCode.UpArrow))
{
m_Rigidbody.velocity= transform.up * Time.deltaTime * m_Speed;
}
if (Input.GetKey(KeyCode.DownArrow))
{
m_Rigidbody.velocity = transform.up * Time.deltaTime * (-m_Speed);
}
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(0, 0, -1 * m_Speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(0, 0, 1 * m_Speed * Time.deltaTime);
}
}
}
'''
Can you please tell me how to fix it? Thanks for your answers.
Note that in general a velocity already is a value in absolute units per second and you don't want to multiply by Time.deltaTime in that case.
Also in general whenever dealing with Physics I wouldn't use transform at all but rather do everything via the Rigidbody.
And then simply when you don't press a key do
if (Input.GetKey(KeyCode.UpArrow))
{
m_Rigidbody.velocity = Quaternion.Euler(0, 0, m_Rigidbody.rotation) * Vector3.up * m_Speed;
}
else if (Input.GetKey(KeyCode.DownArrow))
{
m_Rigidbody.velocity = Quaternion.Euler(0, 0, m_Rigidbody.rotation) * Vector3.down * m_Speed;
}
else
{
m_Rigidbody.velocity = Vector2.zero;
}
For the rotation I would also rather go
m_Rigidbody.rotation += m_Speed * Time.deltaTime;
and
m_Rigidbody.rotation -= m_Speed * Time.deltaTime;
I am trying to make a FPS game but when I press w for a bit and then release it slides a bit further than wanted. I am pretty new to Unity and think it has something to do with the updates.
Code:
public float moveSpeed = 5f;
public float jumpForce = 5f;
public CharacterController controller;
private Vector3 moveDirection;
public float gravityScale;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
float yStore = moveDirection.y;
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection.normalized * moveSpeed;
moveDirection.y = yStore;
if (controller.isGrounded)
{
moveDirection.y = 0f;
if (Input.GetButtonDown("Jump"))
{
moveDirection.y = jumpForce;
}
}
moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale);
controller.Move(moveDirection * Time.deltaTime);
}
add a physics material to your ground and set the dynamic friction to 1. Next, set the static friction from 0.5 to 1. And last but not least, set the bounciness to 0.
Play around with these values a bit until you find something that is satisfactory.
here is the link to the documentation:
https://docs.unity3d.com/Manual/class-PhysicMaterial.html
it basically explains what each property does.
I have began developing an fps script and followed a tutorial to help with the script. Everything works great now but the only issue is any objects in the view seem to stutter whenever the player is moving and rotating at the same time.
The script for the player's movement and camera rotation is below.
Can anybody point me in the right direction?
Thank you.
{
public Transform cam;
public Rigidbody rb;
public float camRotationSpeed = 5f;
public float camMinimumY = -60f;
public float camMaximumY = 75f;
public float rotationSmoothSpeed = 10f;
public float walkSpeed = 9f;
public float runSpeed = 14f;
public float maxSpeed = 20f;
public float jumpPower = 30f;
public float extraGravity = 45;
float bodyRotationX;
float camRotationY;
Vector3 directionIntentX;
Vector3 directionIntentY;
float speed;
public bool grounded;
void Update()
{
LookRotation();
Movement();
ExtraGravity();
GroundCheck();
if(grounded && Input.GetButtonDown("Jump"))
{
Jump();
}
}
void LookRotation()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
bodyRotationX += Input.GetAxis("Mouse X") * camRotationSpeed;
camRotationY += Input.GetAxis("Mouse Y") * camRotationSpeed;
camRotationY = Mathf.Clamp(camRotationY, camMinimumY, camMaximumY);
Quaternion camTargetRotation = Quaternion.Euler(-camRotationY, 0, 0);
Quaternion bodyTargetRotation = Quaternion.Euler(0, bodyRotationX, 0);
transform.rotation = Quaternion.Lerp(transform.rotation, bodyTargetRotation, Time.deltaTime * rotationSmoothSpeed);
cam.localRotation = Quaternion.Lerp(cam.localRotation, camTargetRotation, Time.deltaTime * rotationSmoothSpeed);
}
void Movement()
{
directionIntentX = cam.right;
directionIntentX.y = 0;
directionIntentX.Normalize();
directionIntentY = cam.forward;
directionIntentY.y = 0;
directionIntentY.Normalize();
rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
if (Input.GetKey(KeyCode.LeftShift))
{
speed = runSpeed;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
speed = walkSpeed;
}
}
void ExtraGravity()
{
rb.AddForce(Vector3.down * extraGravity);
}
void GroundCheck()
{
RaycastHit groundHit;
grounded = Physics.Raycast(transform.position, -transform.up, out groundHit, 1.25f);
}
void Jump()
{
rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
}
}
This probably happens because the frame needs to update the camera rotation and the player position at the same time. i would suggest doing the rotation of the camera in fixed update. because this will run at the end of each frame.
like this:
void FixedUpdate()
{
LookRotation();
}
another thing i would suggest is to move the player while the groundcheck is being ran, because if you do it seperately i can see a bug coming up when the player moves faster then the code can run or something. so a tip would be or to run it inside the movement method, or call the method while you are calling the movement method.
this:
void Movement()
{
directionIntentX = cam.right;
directionIntentX.y = 0;
directionIntentX.Normalize();
directionIntentY = cam.forward;
directionIntentY.y = 0;
directionIntentY.Normalize();
rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
if (Input.GetKey(KeyCode.LeftShift))
{
speed = runSpeed;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
speed = walkSpeed;
}
GroundCheck();
}
or litteraly copy and paste the code within your movement method.
void Update ()
{
Vector3 input = new Vector3 (0, 0, 1);
Vector3 direction = input.normalized;
Vector3 velocity = direction * speed;
Vector3 moveAmount = velocity * Time.deltaTime;
transform.position += moveAmount;
if(Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
player.AddForce (Vector3.up * jumpForce, ForceMode.Impulse);
}
}
Since Time.deltaTime varies moveAmount also varies for every jump making the distance of the jump vary slightly.
The ball is to jump between blocks separated by a fixed gap and therefore the above behaviour causes problems.
Is there any way I can fix this and make fixed length jumps?
You can use CharacterController for this. Make sure you have a CharacterController and Collider attached to your gameobject. Also if you have a rigibody attached to your game object it may cause it to behave unexpectedly so you might have to contraint it.
public CharacterController controller;
private float verticalVelocity;
private float gravity = 25.0f;
private float jumpForce = 15.0f;
void Awake () {
controller = GetComponent<CharacterController>();
}
void Update () {
if( controller == null )
return;
if( controller.isGrounded)
{
verticalVelocity = -gravity * Time.deltaTime;
if( Input.GetKeyDown(KeyCode.Space) )
{
verticalVelocity = jumpForce;
}
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 moveVector = Vector3.zero;
moveVector.x = moveHorizontal * 5.0f;
moveVector.y = verticalVelocity;
moveVector.z = moveVertical * 5.0f;
controller.Move(moveVector * Time.deltaTime);
}
Check this tutorial for reference: https://www.youtube.com/watch?v=miMCu5796KM
Hi everybody I am having a problem with my game, the problem is based when I switch the materials so it can face the other direction (it is a 2d game). This affects the animation which is controlled by the renderer.material.mainTextureOffset but I have no idea why this is not working.
code in c#:
using UnityEngine;
using System.Collections;
public class character : MonoBehaviour {
public float forwardSpeed = 10.0f;
public Material newMaterialRefcs1;
public Material newMaterialRefcs2;
// Use this for initialization
void Start () {
}
//error is occurring here !!!!!!!! below Important. The 2 if statements below
// Update is called once per frame
void Update () {
if( Input.GetKey(KeyCode.D)){
renderer.material.mainTextureOffset = new Vector2(0.25f, 0);
transform.position += -transform.right * forwardSpeed * Time.deltaTime;
renderer.material = newMaterialRefcs1;
}if( Input.GetKey(KeyCode.A)){
renderer.material.mainTextureOffset = new Vector2(0.25f, 0);
transform.position += transform.right * forwardSpeed * Time.deltaTime;
renderer.material = newMaterialRefcs2;
}
}}
I'm not sure exactly what your problem is but it sounds like you're trying to adjust one setting in the first script then add a new material in the second script. If that is the case then, when you assign the new material in the second script you are replacing the material completely meaning the renderer.material.mainTextureOffset.x that you set in the first gets overwritten.
Try keeping the offset in a separate variable that you can assign to the new texture when it is added in the second script.
Try to use other shader. Diffuse, for example.
Also, check in inspector, is this value really changed. May You rewrite it in other script?
I have figured it out with some help from the unity forums took a while but here it is:
using UnityEngine;
using System.Collections;
public class character : MonoBehaviour {
public float forwardSpeed = 20.0f; public float rot = 0f;public float jumpSpeed = 100;public float gravity = 30f;
public Material newMaterialRefcs1;
public Material newMaterialRefcs2;
void Start () {
}
public float scrollSpeed = 0.25F;
void Update () {
if( Input.GetKey(KeyCode.RightArrow)){
scrollSpeed += 0.25f;
transform.position += -transform.right * forwardSpeed * Time.deltaTime;
renderer.material = newMaterialRefcs1;
float offset = scrollSpeed;
renderer.material.SetTextureOffset("_MainTex", new Vector2(offset, 0));
}if( Input.GetKey(KeyCode.LeftArrow)){
scrollSpeed += 0.25f;
transform.position += transform.right * forwardSpeed * Time.deltaTime;
renderer.material = newMaterialRefcs2;
float offset = scrollSpeed;
renderer.material.SetTextureOffset("_MainTex", new Vector2(offset, 0));
}
Vector3 isgrounded = transform.TransformDirection(Vector3.up);
if( Input.GetKeyDown(KeyCode.Space)&& Physics.Raycast(transform.position, isgrounded, 6)){
transform.position -= transform.up * jumpSpeed * Time.deltaTime*2;
}
Physics.gravity = new Vector3(0, gravity, 0);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z);
}
}