I'm trying my first test-game with Unity, and struggling to get my bullets to move.
I have a prefab called "Bullet", with a RigidBody component, with these properties:
Mass: 1
Drag: 0
Angular drag: 0,1
Use grav: 0
Is Kinematic: 0
Interpolate: None
Coll. Detection: Discrete
On the bullet prefab, I have this script:
public float thrust = 10;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.AddForce(transform.forward * 100, ForceMode.Impulse);
}
On my playerController script (not the best place for this, I know):
if (Input.GetAxisRaw("Fire1") > 0)
{
var proj = Instantiate(projectile, transform.position, Quaternion.identity);
}
When I click my mouse, the bullet gets created, but doesn't move. I've added velocity to the rigidbody, which works, but I can't get it to move in the right direction. After googling around, it seems I need to be using rigidBody.AddForce(), which I did, but still can't get my bullet to move.
I've seen the other solution, but this did not work for me either.
Any advice would be appreciated.
Screenshot:
When you're working with 2D in Unity, the main camera basically becomes an orthographic camera (no perspective effects) looking sideways at the game scene along the z-axis. Incidentally, the "forward" direction of a non-rotated object is also parallel to the z-axis.
This means that when you apply a force along transform.forward, you're sending the object down the z-axis - which will not be visible to an orthographic camera looking in the same direction. The quick fix here would be to use a direction that translates to an x/y-axis movement, like transform.up or transform.right.
As derHugo also mentioned in the comments, you might want to look into using Rigidbody2D. There are some optimizations that will allow it to behave better for a 2D game (though you may not notice them until you scale up the number of objects).
Related
I'm new to this, I'm making an obstacle dodging game, and part of the losing conditions is that if the player object falls below -1 on the y axis then the player loses the game, but every time I run the game and intentionally go off the edge of the ground, the player object just floats. I've double checked that the Rigidbody for the player uses gravity, and even checked my scripts for logic errors, nothing has worked. got any ideas on how to fix it?
I've already added the code rb.useGravity = true;
here's the script for the player's movement:
`
using UnityEngine;
public class movement : MonoBehaviour
{
public Rigidbody rb;
public float ForwardMomentum = 1000f
public float SidewaysMomentum = 500f
void FixedUpdate()
{
rb.useGravity = true;
rb.AddForce(0, 0, FowardMomentum * Time.deltaTime);
if (Input.GetKey("d"))
{
rb.AddForce(SidewaysMomentum * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
else if (Input.GetKey("a"))
{
rb.AddForce(-SidewaysMomentum * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
}
To make a reproducible example for this, all you need to do is:
Add a cube game object (I believe that the box collider and mesh renderer should already be loaded in there)
Add the Rigidbody component and tick use gravity (As well as ticking freeze rotation on the x axis)
Add the new script with the code from above (please fix any errors you find to make it work and let me know how you did it :D)
Add a ground floor and just make it so the player cube is sitting on top of it
then just run it a couple of times and see how it goes, if nothing is out of the ordinary then idk what's going on with my unity
In unity using Rigidbodies is sometimes a bit difficult. But the solutions to these problems come pretty easily.
-Firstly Check if you even have applied a rigidbody (mostlikely you do else your game wouldn't run)
-Check if you have accidently selected "IsKinematic" which could cause your gravity not to be used on that rigidbody.
-Check the way you get the rigidbody in your script, if the script is correctly applied to your gameobject. (if the rigidbody is gotten via the inspector you might need to just drag and drop it into the script)
-Check the collider on your ground if it isn't bigger then the visual
I'm currently creating a simple game like the Angry Bird. So I succesfully created something like that and I'm currently facing a problem where in I want to shoot the bird infinitely like if it hits the wall it should just bounce back and if it hits a wall again it will bounce back like infinite.
Here's my shoot code
public float force = 1300;
private void OnMouseUp()
{
// Disable IsKenematic
GetComponent<Rigidbody2D>().isKinematic = false;
// Add the Force
Vector2 dir = startPos - (Vector2)transform.position;
GetComponent<Rigidbody2D>().AddForce(dir * force);
//Remove the script (not the gameobject)
Destroy(this);
}
EDIT
Just to add an information I am using Physics 2D material
Friction: 0.8
Bounciness: 0.45
Set the Rigidbody.Drag of the game object to 0.
More info on what Drag does: https://docs.unity3d.com/ScriptReference/Rigidbody-drag.html
You should set the Rigidbody.GravityScale too to 0.
If you want to control the constant speed too change Rigidbody.Velocity.Magnitude.
Originally answered HERE , you could use the suggested ZeroFriction material for walls, etc. I've used this in one previous attempt and it worked fine.
Yehey thanks for the help guys finally able to control the ball by doing this setting on the rigidbody and physics 2d material
rigidbody
drag all off
gravity is zero
physics 2d material
friction is 0
bounciness is 1
THANK YOU
I know this is quite the noob question, but whatever, there's only one way to learn.
I've created an empty GameObject in Unity, attached a script that is supposed to move a cube(my player) and gave my cube the tag "Player". After creating the cube, I was hoping to be able to move the cube without having to put the script on the cube itself. When the script is on the cube, it moves without a problem (I know this is how it probably should be done, but for trying to learn new things I wanted to do it this way).
Player Controller script
Cube properties
After failing to find the answer through Google, any insight at all is greatly appreciated!
Thank you
Update!
Here's the code as text now, since it was asked for.
public class GameCoreController : MonoBehaviour {
private GameObject PlayerMove;
public Rigidbody rb;
void Start ()
{
PlayerMove = GameObject.FindGameObjectWithTag("Player");
rb = GetComponent<Rigidbody>();
}
void Update()
{
// character movement
if (Input.GetKey(KeyCode.W))
{
PlayerMove.transform.Translate(0, 0, 0.25f);
}
if (Input.GetKey(KeyCode.S))
{
PlayerMove.transform.Translate(0, 0, -0.25f);
}
if (Input.GetKey(KeyCode.A))
{
PlayerMove.transform.Translate(-0.25f, 0, 0);
}
if (Input.GetKey(KeyCode.D))
{
PlayerMove.transform.Translate(0.25f, 0, -0);
}
}
I've updated the code from before to include PlayerMove.transform.Translate but I still have the same issue with the cube note moving. I've also included screenshots of my scene with the cube and the GameCoreController; the empty GameObject holding the script that is supposed to control the cube.
Thanks again for the help guys.
Update 2!
After deleting the cube and re-insert it into the scene it now moves. Thanks for the help everyone.
The reason that the cube won't move because in your code you didn't move its transform but you move the transform of the gameobject that you attached this script to.
transform.Translate move the transform of the gameobject that this script attach to. So if you want to move the cube, all you need to do is change from transform.Translate to PlayerMove.transform.Translate which will move the transform of PlayerMove gameobject which is your cube with "Player" tag on it
^ All of the above. Plus, in the screenshot, your rigidbody is not set to "is kinomatic". This means that physics will still be applied to it (like gravity). Rule of thumb: If you have a moving object where collision is important, it will need a rigidbody and a collider. If the object is not moved with physics commands (eg rigidbody.AddForce()) but rather manipulating the transform as you are, set the rigidbody "isKinomatic" property to true.
I have a small piece of code to make a sprite (in a 3D world) always face the camera (It has to be in 3D space).
public class CS_CameraFacingBillboard : MonoBehaviour {
private Camera m_Camera;
private void Start()
{
m_Camera = Camera.main;
}
void Update()
{
transform.LookAt(transform.position + m_Camera.transform.rotation *
Vector3.forward, m_Camera.transform.rotation * Vector3.up);
}
}
This code ensures the sprite is always facing the camera, causing it to lean backwards as the camera in above the sprite facing down in a 45 degree agle. When I put a rigidbody on the sprite, the sprite moves on its own towards the direction its leaning. The rigidbody works fine without this code attached.
How can I have a sprite that always faces the camera, and has a rigidbody attached?
It seems you've left the rigidbody as Dynamic, you should set it to Kinematic.
EDIT: After you comments, I checked myself inside Unity, and probably I've recreated the behaviour you described. It happens to me too IF I use a Box Collider on the sprite without locking its rigidbody rotation.
So you have three possible solutions:
Use a Box Collider and under Constraints of the rigidbody freeze the rotation:
Use a Sphere Collider (or another one that doesn't behave like the box one, you can check them out in play mode).
Split the components over two game object, a parent and a child. The parent will have all the components except the sprite renderer and the camera script, which will be on the child. This option is the most flexible and less restraining. You can have the box collider without freezing rotations, etc.
Another thing, you can avoid the use of the LookAt method, by simply using:
transform.rotation = m_Camera.transform.rotation;
they have the same outcome.
I'm trying to implement this tutorial on the unity site. I've went over the unity blog and havn't found the solution to my problem there.
I have a simple Rigidbody sphere object over a plane.
The sphere is default sized, and set on: (0,0.5,0).
The plane is also default sized, and set on the origin (0,0,0). Those are the only components I use.
What I'm trying to do is to write a simple C# script behavior for the sphere that will move it across the plane, like so:
public class Controller : MonoBehaviour {
private Rigidbody rb; // Holds the body this script is affecting.
// Called at the start, to set variables.
void Start()
{
rb = GetComponent<Rigidbody>(); // Get the body, if there is one.
}
//For physical changes.
void FixedUpdate()
{
float Horizontal = Input.GetAxis ("Horizontal"); // Get horizontal movement from input.
float Vertical = Input.GetAxis ("Vertical"); // Get vertical movement from input.
Vector3 Movement = new Vector3 (Horizontal, 0.0f, Vertical); // Declaring the movement I'd like to add to the RB. Y axis is irrelevant. X,Z - controlled by user input.
rb.AddForce (Movement); // Making the movement.
}
}
I attached this behavior to the sphere, expecting It'd move when I hit some input key.
Despite this, when I play the project, everything compiles fairly well but the sphere just doesn't move regardless of what I type.
What am I missing?
EDIT: If it's relevant, I also have problems opening the Unity c# code editor (forgot it's name). Whhenever I click open, it just instantly closes. I do everything on Visual Studio.
EDIT 2: My bad, I just figured out I have console Errors. I get the following one:
MissingComponentException: There is no 'Rigidbody' attached to the "Player" game object, but a script is trying to access it.
You probably need to add a Rigidbody to the game object "Player". Or your script needs to check if the component is attached before using it.
UnityEngine.Rigidbody.AddForce (Vector3 force) (at C:/buildslave/unity/build/artifacts/generated/common/modules/NewDynamics.gen.cs:706)
Controller.FixedUpdate () (at Assets/_Scripts/Controller.cs:20)
"Player" is the name I gave the sphere.
I forgot to attach the Rigidbody to the sphere.