I'm new to Yonti, I'm trying to build a simple maze game, and I'm trying to make the player's object move, but I'm not been able to do that for a few hours.
This is the code I wrote down:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerMover : MonoBehaviour
{
public float speed;
public 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);
}
}
this is the player object:
I do not understand where I have a problem. I added the script to the player object and I get no error message. It just does not move, I do not understand why.I set "RigidBody" and gave speed to the object, I do not understand where there is an error.
Try turning off isKinematic on your rigidbody. The IsKinematic is used for animation/scripted moving with rb.position. In return, this will disable all forces on the rigidbody, causing your rb.AddForce to be ineffective.
If isKinematic is enabled, Forces, collisions or joints will not affect the rigidbody anymore. (This is taken from documenation)
I would also be cautious of the Fixed Update, as it can loose Input signal with KeyDown and KeyUp; but the way you are using it should be fine.
Rigidbody probably interacts with terrain so; instead of using "rigidbody" you should use CharacterController https://docs.unity3d.com/ScriptReference/CharacterController.html
When you use public variables you always need to assign them in some ways because Unity will try to search from the Inspector firstly. You can simply fix your problem by setting the rigidbody to private and then assign it in the Start() like you were doing.
If you want to set the Rigidbody to be public you must assign it in the inspector by dragging the component of the rigidbody inside the inspector of the script
Related
I was attempting to make a top down 2D shooter using Unity. My code contains no errors that I could see, RigidBody2D and PlayerMovement (code for the player to move) have been added to the sprite, and RigidBody2D has been added to the PlayerMovement. My move speed is set to 5. Please let me know what I can do to fix this issue!
Code:
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed;
public Rigidbody2D rb;
Vector2 movement;
void Update()
{
MovementInput();
}
private void FixedUpdate()
{
rb.velocity = movement * moveSpeed;
}
void MovementInput()
{
float mx = Input.GetAxisRaw("Horizontal");
float my = Input.GetAxisRaw("Vertical");
movement = new Vector2(mx, my).normalized;
}
}
Use your character sprite as the mouse cursor instead to write a code to make the player follow the mouse pos
If you really want to move your player via script this video will help you https://www.youtube.com/watch?v=0Qy3l3VuF_o
Have a good day :)
Check if your rigidbody2D's Body type is set to static, If it is then set it to kinematic or dynamic.
Also where did you import the script to?
Your code is not the problem, I tested it myself! Although you could move MovementInput(); to the FixedUpdate. Its not required though.
Edit: Image of the inspector as i have it if it helps
I have a rectangle player sprite with a Box Collider 2D and a Rigidbody2D attached. I also have a script for point-and-click movement attached to the player object (i.e. player moves to mouse click position). However as soon as the player character hits a collider, it starts to jitter rather than just fully stop. I don't know a lot about Unity physics other than what I've picked up in a few tutorials, so I'll include as much relevant information as I can.
The Rigidbody 2D component has all forces set to 0, except for mass being 0.0001. The body type is dynamic, and collision detection is set to continuous. My movement script looks like this, got it straight from a tutorial:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
public float speed = 1;
private Vector3 target;
void Start()
{
target = transform.position;
}
void Update()
{
if (Input.GetMouseButtonDown(0)) {
target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
target.z = transform.position.z;
}
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
}
Is there an easier way to implement smooth point-and-click movement?
I want to make a pong game but my ball isn't flying like I want. My ball is getting impacted from gravity. I know i need to set the body type from dynamic to kinematic but if I use kinematic, my ball isnt moving anymore because my ball flys with addforce. Which force can I use so that I can kinematic use?
public class BallPhysics : MonoBehaviour {
public Rigidbody2D rbBall;
public float SpeedX = 10.0f;
public float SpeedY = 5.0f;
void FixedUpdate()
{
rbBall.AddForce(new Vector2(SpeedX, SpeedY)); // my ball is flying
}
void OnCollisionEnter2D(Collision2D collisionInfo) // collision for the walls
{
if (collisionInfo.collider.tag == "wall")
{
SpeedX = -SpeedX;
SpeedY = -SpeedY;
}
}
}
There is no useGravity in RigidBody2D but you can simply leave IsKinematic disabled and rather also disable it's gravityScale
private void Start()
{
rbBall.gravityScale = 0;
}
this has the same effect as disabling useGravity on a RigidBody. Especially in the context of your question I really like the note
it may be easier to implement a flying character by turning off its gravity rather than simulating the forces that keep it aloft.
;)
or alternatively disable gravity for the entire scene/project using Physics2D.gravity
private void Start()
{
Physics2D.gravity = Vector2.zero;
}
To the question itself
Is there an alternative for addforce if I want use kinematic?
No and yes...
From RigidBody2D.isKinematic
Should this rigidbody be taken out of physics control?
If this property is set to true then the rigidbody will stop reacting to collisions and applied forces. This can be useful when an object should usually be controlled "kinematically" (ie, non-physically) but then sometimes needs physics for realism. For example, a human character is usually not implemented using physics but may sometimes be thrown through the air and collide with objects as the result of an impact or explosion.
Or also from Rigidbody.isKinematic
If isKinematic is enabled, Forces, collisions or joints will not affect the rigidbody anymore. The rigidbody will be under full control of animation or script control by changing transform.position.
So simply use the
transform.position = ...
as usual.
For having something similar to AddForce you could store a local speed vector and add more speed like
// public so you can also configure
// it in the inspector or set it from another script
public Vector2 speed;
public void AddForce(Vector2 force)
{
speed += force;
}
private void Update()
{
transform.position += speed * Time.deltaTime;
}
However in your case you don't want to add speed each frame but probably only set a certain speed once at start and on collisions.
I'm writing a script in C# in Unity that essentially functions as a switch to turn gravity on or off for a 2D Rigidbody. When the game starts, gravity should be 0 for the Rigidbody. Then when the user taps the space bar, gravity is supposed to increase to 3 (which is does). Then, however, when the player collides with a gameObject labeled 'InvisGoal', the player should teleport to another location and then gravity should be 0 again. However, the player always falls after coming in contact with InvisGoal and teleporting and I can't figure out why. This is my first project in C# so sorry for any obvious errors.. The script is here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallLaunch : MonoBehaviour {
private Rigidbody2D myRigidBody;
public GameObject Ball;
// Use this for initialization
void Start ()
{
myRigidBody = GetComponent<Rigidbody2D> ();
GetComponent<Rigidbody2D>().gravityScale = 0f;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown ("Jump"))
{
GetComponent<Rigidbody2D> ().gravityScale = 3f;
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "InvisGoal")
{
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
transform.position = new Vector3 (0.61f, 1.18f, 0f);
return;
}
}
}
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
This is likely what is causing the problem.
It sounds like the RigidBody2D you are referencing to in this line is not the same as the one you retrieved beforehand with GetComponent().
GetComponent returns the component of the GameObject you call it from. Therefore in the code I mentioned above,
Ball.gameObject.GetComponent<RigidBody2D>()
and
GetComponent<RigidBody2D>()
would give you an two different RigidBody2D component if the field Ball does not refer to the same GameObject your BallLaunch script is attached to.
[
Supposing BallLaunch script is attached to the Ball you want to set the gravity of (As picture above)
Simply change:
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
To
GetComponent<Rigidbody2D>().gravityScale = 0f;
Also, since you already referenced your RigidBody2D in your Start method to the field myRigidBody, you can replace all subsequent GetComponent with myRigidBody.
GetComponent<Rigidbody2D>().gravityScale = 0f;
To
myRigidBody.gravityScale = 0f;
I have been trying to make a movement script for my player in a 2D game but without success. I do not know why it is not working.
The problem is that the player isn't moving. I have a RigidBody attached and gravity on. (Not sure if gravity makes such a difference but I just thought to mention it.)
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public Rigidbody rb;
public float speed = 10;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
float mx = Input.GetAxisRaw("Horizontal");
float mz = Input.GetAxisRaw("Vertical");
Vector3 movement = new Vector3(mx, 0.0f, mz);
Debug.Log(movement);
rb.AddForce(movement * speed * Time.deltaTime);
}
}
You may wanna make sure you are adding enough force to actually cause the player to move. Try increasing the force variable incrementally until you see a change. Hope this helps!