So I have been stuck on player movement for 15 hours total. My player jitters while it moves. I notice that the jitters aren't bad if:
A) I put CamPos code in the same lateUpdate() Function as PlayerMovement code
B) If I lower the fixed timestep under Time in project settings (makes jitter less notable)
I want to make it so that my player doesn't jitter using the right methods. My player has isKinematic off because it causes him to go through walls. I move using rigidbody movePosition because I don't know how to use rb.velocity to make the player move in the same direction as the camera.
I am using a camera for the third person and using rigidbody for movement.
Here's my current code on the player PlayerMovement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed;
public Rigidbody rb;
public Transform camPos;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
camPos = Camera.main.transform;
}
private void FixedUpdate()
{
if (Input.GetKey("w"))
rb.MovePosition(transform.position + (camPos.forward * speed));
if (Input.GetKey("s"))
rb.MovePosition(transform.position + (-camPos.forward * speed));
if (Input.GetKey("d"))
rb.MovePosition(transform.position + (camPos.right * speed));
if (Input.GetKey("a"))
rb.MovePosition(transform.position + (-camPos.right * speed));
}
}
Here's my current code on the camera CamPos:
//Hakeem Thomas
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamPos : MonoBehaviour
{
public Transform target;
public float smoothTime = 0.5F;
private Vector3 velocity = Vector3.zero;
public GameObject player;
private float mouseX, mouseY;
public int mouseX_Speed, mouseY_Speed;
//mouseSensitivity
public int turnSpeed;
void getMouseXY()
{
mouseX += Input.GetAxis("Mouse X") * smoothTime;
mouseY -= Input.GetAxis("Mouse Y") * smoothTime;
}
void LateUpdate()
{
getMouseXY();
// Define a target position above and behind the target transform
Vector3 targetPosition = target.TransformPoint(new Vector3(0, 1.5f, -2.5f));
// Smoothly move the camera towards that target position
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
transform.LookAt(target);
target.rotation = Quaternion.Euler((mouseY * mouseY_Speed), (mouseX * mouseX_Speed), 0);
player.transform.rotation = Quaternion.Euler(0, (mouseX * turnSpeed), 0);
}
}
I also tried using Vector3's and input Axis to move, but it makes the player move in an awkward way(Controls tied to one direction). I also tried using cinemachine and turned off all my scripts on my camera to make sure the camera wasn't jittering.
Rigidbody is the physic representation of your gameobject. The thing is you doesn't use the velocity / movement of the gameobject using dirrectly the rb.MovePosition().
But it is fine ! according to the documentation you have to enable the rigidbody "interpolation" to create a smooth transition between frames.
Hope i helped you and it will works for you !
Edit
dont forget to multiply your vector by Time.fixedDeltaTime inside FixedUpdate()
Related
If you dont collide with something you can fly! its really strange, please help me if you can.
i dont know how to fix it cause i am new in it.
Here is a script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Movement : MonoBehaviour
{
public float speed = 4.0f;
public float gravity = -9.8f;
private CharacterController _charCont;
// Use this for initialization
void Start()
{
_charCont = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float deltaX = Input.GetAxis("Horizontal") * speed;
float deltaZ = Input.GetAxis("Vertical") * speed;
Vector3 movement = new Vector3(deltaX, 0, deltaZ);
movement = Vector3.ClampMagnitude(movement, speed); //Limits the max speed of the player
// movement.y = gravity;
movement *= Time.deltaTime; //Ensures the speed the player moves does not change based on frame rate
movement = transform.TransformDirection(movement);
_charCont.Move(movement);
}
}
I don't know that CharacterController but it sounds like it takes the global movement vector.
After
movement = transform.TransformDirection(movement);
you should erase the Y component
movement.y = 0;
I am not sure why but I am starting a new project in which a player moves with WASD and points towards the mouse pointer. This is all the code I have so far as It is only early into development but any help would be nice. Here is a little pic of what I currently have on my player...
ANY HELP WILL BE AMAZING!
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public Rigidbody2D rb;
Vector2 movement;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(
mousePosition.x - transform.position.x,
mousePosition.y - transform.position.y
);
transform.up = direction;
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
Set the gravity scale to 0 or set Rigidbody2D body type to Kinematic.
Kinematic rigidbodies can only be moved via script and are not participated in regular physics unlike dynamic rigidbody. So if you don't want some 'automatic' behaviors always use kinematic body type, otherwise if only problem is automatic 'moving down' issue then set gravity scale to 0 and that's all.
I think both will work in your case. And also here is some further info
I have a problem. I want my enemy to follow the player and try to hit it with the full speed but I cant achieve it. It appears to have faster speed value when its far away and slows down while getting closer to the player.
How to make it move at the same speed?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dotty : MonoBehaviour
{
[SerializeField] Transform playerTarget;
Vector3 direction;
Rigidbody2D rb;
float speed = 2.2f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
direction = playerTarget.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb.rotation = angle;
}
private void FixedUpdate() {
rb.MovePosition(transform.position + direction.normalized * speed);
}
}
first of all change this line :
rb.MovePosition(transform.position + direction.normalized * speed);
to this:
rb.MovePosition(transform.position + direction.normalized * speed * Time.fixedDeltaTime);
and the reason it slows down is probably because the target "Z" position is not "0" (same as player "Z" position).
I need to rotate the camera around my player gameobject while holding the left mouse button. How would I approach this?
Also, I've read a bit on Vector 3, but I don't have a full understanding of it. Anybody who could explain it would be greatly appreciated.
I've looked at youtube videos and this one is exactly the concept I was looking for. I was just having trouble applying it to my code.
I'm on a bit of a time crunch, exams are nearing and my teacher hasn't explained most things that are explained in the video.
// This is my code inside the camera which follows the ball/player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScriptBallCam : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
void Start()
{
offset = transform.position - player.transform.position;
}
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
//End of code inside camera
//Code inside of player/ball
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScriptBall : MonoBehaviour
{
public float speed;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
rb.AddForce(movement * speed);
}
// end code
Results I'm expecting are exactly shown at 1:22 in
https://www.youtube.com/watch?v=xcn7hz7J7sI
Try this. The script goes on your camera.
Basically this script works by first getting the direction your mouse has moved in. In this case the X axis Mouse X (left/right direction). Then we take our rotation speed turnSpeed, and use it to rotate around the player by that amount of degrees using Quaternion.AngleAxis. Finally we make sure that the camera is always looking at the player by using transform.LookAt
using UnityEngine;
using System.Collections;
public class OrbitPlayer : MonoBehaviour {
public float turnSpeed = 5.0f;
public GameObject player;
private Transform playerTransform;
private Vector3 offset;
private float yOffset = 10.0f;
private float zOffset = 10.0f;
void Start () {
playerTransform = player.transform;
offset = new Vector3(playerTransform.position.x, playerTransform.position.y + yOffset, playerTransform.position.z + zOffset);
}
void FixedUpdate()
{
offset = Quaternion.AngleAxis (Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * offset;
transform.position = playerTransform.position + offset;
transform.LookAt(playerTransform.position);
}
}
There is a lot of information on this topic over here:
https://answers.unity.com/questions/600577/camera-rotation-around-player-while-following.html
I am trying to make a game where a ball will be ricocheting off several different colliders on screen. Based on what I researched I got some code that seemed to make sense at first but does not seem to work at all. I am testing it out just by having the ball fall down onto a 2D floor with a box collider attached to it. However once it collides with the floor it just stops there and doesn't bounce back up. I tried disabling "Queries Start in Colliders" in the project settings and offsetting the origin position of the RaycastHit2D so that it would not detect the collider its attached to but that still didn't work. I don't think the RaycastHit2D is working at all because it doesn't even display anything in the console. Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBehavior : MonoBehaviour {
Rigidbody2D rigidbody;
public Vector2 startPos;
public float speed;
public float hitOffset;
Vector3 vector = new Vector3(0, 5,0); //used to offset origin point of RaycastHit2D hit
private void OnEnable()
{
rigidbody = GetComponent<Rigidbody2D>();
this.transform.position = startPos;
}
private void Update()
{
transform.Translate(Vector2.down * speed * Time.deltaTime);
RaycastHit2D hit = Physics2D.Raycast(transform.position + vector, - transform.up, speed * Time.deltaTime + hitOffset);
Debug.DrawRay(transform.position, -transform.up, Color.red);
Ray2D ray = new Ray2D(transform.position, -transform.up);
if (hit)
{
Debug.Log(speed * Time.deltaTime + hitOffset);
Debug.Log(hit.collider.name);
Vector2 reflectDir = Vector2.Reflect(ray.direction,hit.normal);
float rotation = Mathf.Atan2(reflectDir.y, reflectDir.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0, 0, rotation);
}
}
}
Is my math bad? Any help is very appreciated, thanks.