hi everyone so basically I was wondering how I could change this movement script to be with rigidbody. It works the way I want it to with wasd to change look direction and then space to move forward from that direction kinda but I want to convert it all to be done with rigidbody so I can do collisions. Thanks!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fly : MonoBehaviour
{
public float moveSpeed;
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
transform.Translate(new Vector3(0,0,moveSpeed) * Time.deltaTime, Space.Self);
}
float rotatex = Input.GetAxis("Vertical");
float rotatey = Input.GetAxis("Horizontal");
transform.Rotate(0, rotatey, 0, Space.World);
transform.Rotate(-rotatex * 0.5f, 0, 0);
}
}
There are quite a few errors with your code as written. No problem, but you'll probably need to fix all of these before your code starts working as intended. This answer is meant to give you a springboard to google up on some of these errors and wrap your head around the Update() method and how it works in Unity.
First, you'll need to ensure the RigidBody2d component is on your Game Object. That's easy enough to do, right click in the inspector and add the component. Google: "How do I add components to game objects in Unity"
Next, you're going to want to understand how often Update() is called and how it works. Spoiler alert - it's called as fast as your computer can. What that means is that changing the rotation with transform.Rotate every call is likely going to lead to an object that's spinning extremely rapidly. Perhaps rapidly enough that it's spinning more than 360 degrees each frame and just appears to be "twitching" randomly. You'll need to scale your rotation, so Google up "delta time in Unity Update".
Lastly, you're going to want to collect your inputs, which you're doing correctly with Input.GetKey(), although there are lots of ways to skin this cat. Perhaps the most straightforward would be to collect your inputs in one method called GetAllInputs(), set some booleans in that method to things like IsMovingRight or IsJumping and then operate on them in your Update method. This is only one approach, there are literally dozens, and many ways that they can be improved. Google up "Unity Input System", "Unity 2D Physics", and "Finite State Machines" (since you're eventually going to want to have "states" like crouching, jumping, running, hanging on to a wall, etc). It seems like you're writing a platformer, so I'd also watch some of the youtube tutorials on that, and google phrases like "Creating a Unity Platformer Tutorial".
Assuming it works the way you want here is the code using rigidbody (Make Sure Rigid Body is attached to object) This code must be written in Fixed Update as RigidBody based calculation must be done in Fixed Update:
public class Fly : MonoBehaviour
{
public float moveSpeed;
[SerializeField] private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.Space))
{
//transform.Translate(new Vector3(0,0,moveSpeed) *
//Time.deltaTime, Space.Self);
if (rb)
{
rb.MovePosition(new Vector3(0,0,moveSpeed) *
Time.deltaTime);
}
}
float rotatex = Input.GetAxis("Vertical");
float rotatey = Input.GetAxis("Horizontal");
// transform.Rotate(0, rotatey, 0, Space.World);
// transform.Rotate(-rotatex * 0.5f, 0, 0);
if (rb)
{
rb.MoveRotation(Quaternion.Euler(rotatex , rotatey , 0));
}
}
}
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
public Rigidbody rb;
public float MouseSensitivity;
public float MoveSpeed;
public float jumpForce;
void Start ()
{
}
void Update()
{
//Look around
rb.MoveRotation(rb.rotation * Quaternion.Euler(new Vector3(0, Input.GetAxis("Mouse X") * MouseSensitivity, 0)));
//Move
rb.MovePosition(transform.position + (transform.forward * Input.GetAxis("Vertical") * MoveSpeed) + (transform.right * Input.GetAxis("Horizontal") * MoveSpeed));
//Jump
if (Input.GetKeyDown("space"))
{
print("clicked");
rb.AddForce(Vector3.up * jumpForce);
}
}
}
this is my code and a picture of the player object when I'm trying to jump it doesn't work but it does print clicked I tried to do many things but nothing worked so if you know how to solve the issue please tell me
RigidBody.AddForce has a second parameter of type ForceMode that defaults to ForceMode.Force. That particular ForceMode is only good for continual application of force (like a rocket's thruster). For a feature like jumping, you'll either want to use ForceMode.Impulse or ForceMode.VelocityChange.
// Pick one or the other
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
rb.AddForce(Vector3.up * jumpForce, ForceMode.VelocityChange);
Also, make sure your jumpForce value isn't tiny or it'll be an unnoticeably small "jump."
Firstly, physics calculations should generally be calculated inside of FixedUpdate(). This is described in the unity documentation here.
Edit: To make it more clear for the comment on my post. Input should be located inside of the Update() method whilst physics calculations should generally be calculated inside of the FixedUpdate() method.
If it is decided that you want to register input inside of Update() and physics calculations, based on that input, inside of FixedUpdate() then you would use a boolean switch.
Looking at your code I would say that either:
The mass of your Rigidbody is high and your jumpForce variable is too low, trying increasing the value of the jumpForce variable to see if the GameObject moves.
Your Rigidbody has the Is Kinematic checkbox selected.
AddForce is defaulting the ForceMode to ForceMode.Force, try using a different force mode like ForceMode.Impulse to deliver a quick force to the GameObject. In your case this would look like rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
Hope this helps.
I made an 2D endless runner game using Unity, where the Player Object moves upwards, but for the Viewer he remains on the same spot because the Camera is following him. The Following works pretty well, but the problem is that it is making small jumps every few seconds. The jumps are small and thus are not affecting the gameplay in general but they are big enough to make it seem like the game is not running smoothly.
I can't even tell whether it is the Camera that is making the jumps or the Player Object. But I think it is the Camera, because the spawning obstacles are also making jumps. What may be the issue? Am I using the right method for the Camera?
public class Player
{
float speed = 5f;
void Update()
{
transform.Translate(0, speed*Time.deltaTime, 0);
}
}
And this is the Script which is attached to the Camera:
public class CameraFollow
{
private Vector3 FollowVector;
public Transform Player;
void LadeUpdate()
{
FollowVector = Player.position - new Vector3(0, -4f, 10);
transform.position = Vector3.Lerp(transform.position, FollowVector, Time.deltaTime * 4f);
}
}
Does the jump happen every 4 seconds? I think the problem might be in your Vector3.Lerp function. It's basically a loose camera-follow, that takes 4 seconds (Time.deltaTime * 4f) to smoothly go from Point A to point B. Every 4 seconds it resets its path, hence the hop. At least that's my theory.
If you don't mind the camera rigidly following the player, I would just remove the Lerp and just set the transform.position to be the FollowVector value like so:
void LadeUpdate()
{
transform.position = Player.position - new Vector3(0, -4f, 10);
}
Try to use Vector3.MoveTowards
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, Player.position - new Vector3(0, -4f, 10f), step);
I recently posted a problem with a jittering Camera Follow in my 2D Game made in Unity, which was solved here.
However after some time I noticed, that I am still getting jumps. I now know, that the problem lies in the lerp method of my camera follow. Time.deltaTime varies as described in my prior question and thus makes the player move different distances each frame. But because the camera reacts with a delay, you can see the jump on screen (on device even more than in Unity Editor).
A solution would be to detect those Time.DeltaTime jumps and in these cases make the camera imitate that jump somehow, am I correct? What would be a Workaround here?
These are my scripts:
public class Player: MonoBehaviour
{
float speed = 5f;
void Update()
{
transform.Translate(0,speed*Time.deltaTime,0);
}
}
public class CamFollow : MonoBehaviour
{
public Transform Player;
private Vector3 FollowVector;
float transition = 0.05f;
void LateUpdate()
{
FollowVector = Player.position - new Vector3(0, -4.0f, 10);
transform.position = Vector3.Lerp(transform.position, FollowVector, transition);
}
}
Try using Time.fixedDeltaTime. This is like deltatime but it's fixed and so it doesn't very as you said. It does reduce the jittering, but I would recommend using Cinemachine, as it's very performant and you would have a lot of control over it.
I'm creating a game with Unity and I'm learning C#. I needed some help with a bullet firing mechanism for my game so I found the below script on Unity Answers. It works great, but fires the bullet backwards (which would land anyone in the game in a bad situation). Could anyone help? Thank you!
using UnityEngine;
using System.Collections;
public class ShootDemo : MonoBehaviour
{
public Rigidbody projectile;
public float speed = 20;
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Rigidbody instantiatedProjectile = Instantiate(projectile, transform.position,
transform.rotation) as Rigidbody;
instantiatedProjectile.velocity = transform.TransformDirection(new Vector3(0, 0, speed));
}
}
}
What you have would work if you had the forward (blue axis) of the gameobject of ShootDemo pointing in the direction you'd want to shoot.
The fact that does that shoots it in the opposite direction means the forward is pointing is actually pointing in the opposite direction.
Taking that into account by negating speed will reverse the velocity to create the desired effect:
instantiatedProjectile.velocity = transform.forward * -speed;
Or in the format you've already used
instantiatedProjectile.velocity = transform.TransformDirection(new Vector3(0, 0, -speed));
I want to move object to right and to left and i have a weird problem when doing it. I am doing Transform.Translate in update method with If(Input..)
This is my code for moving to right
player.transform.Translate(Vector3.right * Time.deltaTime * varLeftRight, Space.World);
(I tried to use ("player") with gameobject attached in inspector and I tried to use rigidbody ("b") but it doesn't help same issue happens))
where the variable varLeftRight is 125.
I am adding force to go forward in oncollision like this:
b.AddForce(Vector3.forward * speed);
And lets say my player is on coordinates:
-0.074 ->x
-1.5166 ->y
4.173041 -z
I put on player rigidbody is kinematic because I want to test why same issue happens when playing. The problem is when I click once it works and moves right
Cordinates with one click:
1.592691
-1.5166
4.173041
But the problem is when i click twice very fast the player position brakes and goes too much to right.
With twice fast clicks to go to right he goes too much and when I get back one field he need to be on this coordinates:
1.592691
-1.5166
4.173041
and he is on this cordinates:
2.101478
-1.5166
4.173041
Idk did I described issue good. I hope you will understand me,
so when I click once to move with trasnform.translate everything works fine
when I click twice quickly he goes too much to right and when I get back one field to see where is he with one click he is not on right place, to go back to left one field is the same method only with adding left parametar like this:
player.transform.Translate(Vector3.left * Time.deltaTime*varLeftRight, Space.World);
I tried removing the Space.World but it doesn't help.
btw: my obstacle collision have all rigidbody is kinematic to true (Tried without rigidbody same issue happens.
In on Collision I am adding force to go forward no other scripts in code.
public class PlayerControl : MonoBehaviour
{
public float bounce;
public float speed;
public float right;
Rigidbody rb;
public GameObject player;
public float varLeftRight;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
rb.AddForce(Vector3.forward * speed);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("add force");
player.transform.Translate(Vector3.right * Time.deltaTime * varLeftRight, Space.World);
}
if (Input.GetMouseButtonDown(1))
{
player.transform.Translate(Vector3.left * Time.deltaTime*varLeftRight, Space.World);
}
}
private void OnCollisionEnter(Collision collision)
{
rb.AddForce(Vector3.forward * speed);
}
}
I couldn't make sense of why you're adding force on collision, but I have a feeling that's where the issue lies.
I'd comment that out to see if you're still having an issue.
Say that's really the problem, maybe consider only adding force on collision on the proper circumstances (ie. if the player is just colliding with the ground should they get force? or just if colliding with certain elements? etc)