I'm making a 2D Tank shooter game, but I got some problems and questions:
I got some problems with collisions.
GIF of a problem here. Go to tank collision problem. (I can't post more than 2 links because of low reputation, so You will have to go to images manualy, sorry.)
I need to make my tank do not do like shown above. I'm using rigidbody on empty parent and box collider on tank body.
My "Tank (root)" in inspector and "tankBody" (hull) in inspector is here.
tank movement code:
using UnityEngine;
using System.Collections;
public class Movement : MonoBehaviour {
public float thrust;
public float rotatingspeed;
public Rigidbody rb;
void Start () {
rb = GetComponent<Rigidbody>();
}
void Update () {
if (Input.GetKey (KeyCode.W)) {
transform.Translate (Vector2.right * thrust);
}
if (Input.GetKey (KeyCode.S)) {
transform.Translate (Vector2.right * -thrust);
}
if(Input.GetKey(KeyCode.A)) {
transform.Rotate(Vector3.forward, rotatingspeed);
}
if(Input.GetKey(KeyCode.D)) {
transform.Rotate(Vector3.forward, -rotatingspeed);
}
}
}
My bullets fly like they are in zero gravity/space. I need them to do not hover like that(I got similar problem before and I couldn't fixed it..). There is gif in first link in 1.st problem.
shooting code:
using UnityEngine;
using System.Collections;
public class Shooting : MonoBehaviour {
public Rigidbody2D projectile;
public float speed = 20;
public Transform barrelend;
void Update () {
if (Input.GetButtonDown("Fire1"))
{
Rigidbody2D rocketInstance;
rocketInstance = Instantiate(projectile, barrelend.position, barrelend.rotation) as Rigidbody2D;
rocketInstance.AddForce(barrelend.right * speed);
}
}
}
I managed to fix my both problems.
To fix problem number 1. I used add force. My new moving forwand and backward looks like this:
if (Input.GetKey (MoveForward)) {
//transform.Translate (Vector2.right * thrust); OLD !!
rb2D.AddForce(transform.right * thrust * Time.deltaTime);
}
if (Input.GetKey (MoveBackward)) {
//transform.Translate (Vector2.right * -thrust); OLD !!
rb2D.AddForce(transform.right * -thrust * Time.deltaTime);
and I had to adjust my mass to a smaller (from 2000 to 1), thrust to a bigger (from 0.2 to 50000) and set drag into 50, angular drag 100.
2nd problem got fixed by setting drag and angular drag into a bigger value. That's it!
Related
I'm totally new to Unity and game development...I made a 2D object of the car that can move to 8 directions....each direction with the specific animation of the car's movement...Now, how do I make my car move in such a way that if it's moving straight LEFT it shouldn't go immediately straight to RIGHT when turning RIGHT, so I want it to make a proper round turn or a "U TURN" to move towards its opposite direction and obviously the same with UP and DOWN turns....can anyone please help me in at least one way I can fix this?
or the other way to ask this question would be if I'm moving my object to x = -1 direction then on turning to x = 1 it should first go through x = 0 and then x = 1 so that it looks like a turn.
this is the code for my CAR so far..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CARmovement : MonoBehaviour
{
public float speed;
private Rigidbody2D myRigidbody;
private Vector3 change;
private Animator animator;
private Vector3 lastMoveDirection;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
change = Vector3.zero;
change.x = Input.GetAxis("Horizontal");
change.y = Input.GetAxis("Vertical");
UpdateAnimationAndMove();
}
void UpdateAnimationAndMove()
{
if (change != Vector3.zero)
{
MoveCar();
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
animator.SetBool("driving", true);
}
else
{
animator.SetBool("driving", false);
}
}
void MoveCar()
{
myRigidbody.MovePosition(transform.position + change * speed * Time.deltaTime);
}
}
I try an example of rotating a car. We add an object (here I add a car as an example), select the object (car) to create a C# Script script, double-click to open, we define two variables Speed_move, Speed_rot to control the movement speed and Rotation speed and assign values to them. We use Translate to control the forward and backward movement of the cube through the W and S buttons, forward with forward, and back with back; use Rotate to control the rotation of the object through the A and D buttons, up is the Y-axis rotation. The following is the code for the specific rotation.
if (Input.GetKey(KeyCode.W))
{
this.transform.Translate(Vector3.forward * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.S))
{
this.transform.Translate(Vector3.back * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.A))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * -Speed_rot);
}
if (Input.GetKey(KeyCode.D))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * Speed_rot);
}
I've been trying to get this working using pretty much every method I can find (even using the dreaded transform.translate) but I just can't seem to get it working. This is just a draft of the code and if there are any other ways to go about it I'm down to change some stuff.
Currently, he barely moves (it looks like he's getting stuck on the floor somehow.) I'm fairly new to moving objects using rigid bodies so I'm pretty much in the dark on how to solve this issue.
Here's the script from my latest crack at it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerTest : MonoBehaviour
{
public float speed = 10.0f;
public Rigidbody rb;
public Vector3 movement;
// Start is called before the first frame update
void Start()
{
rb.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("w"))
{
movement = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
}
}
void FixedUpdate()
{
moveCharacter(movement);
}
void moveCharacter(Vector3 direction)
{
rb.MovePosition(transform.position + (transform.forward * speed * Time.deltaTime));
}
}
In your code you have your moveCharacter function inside your Update function, enclosed is the fixed one, which should work now. Before your FixedUpdate was not getting called, therefore your moveCharacter function was not as well and your GameObject was not moving.
EDIT 1: You shoud also multiply with your movement direction as well, updated the script to fit that
EDIT 2: I misplaced the curly brackets, fixed that now
EDIT 3: You should also update your movement Vector3 every frame, not if W is pressed, fixed the script again.
EDIT 4: Fixed the movement bug (copy and paste entire script, since i changed more lines)
This is the updated script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerTest : MonoBehaviour
{
public float speed = 10.0f;
public Rigidbody rb;
public Vector3 movement;
// Start is called before the first frame update
void Start()
{
rb.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
movement = new Vector3(Input.GetAxis("Horizontal"), 1f, Input.GetAxis("Vertical"));
}
void FixedUpdate()
{
moveCharacter(movement);
}
void moveCharacter(Vector3 direction)
{
Vector3 offset = new Vector3(movement.x * transform.position.x, movement.y * transform.position.y, movement.z * transform.position.z);
rb.MovePosition(transform.position + (offset * speed * Time.deltaTime));
}
}
References: Rigidbody.MovePosition
I'm following the official multiplayer networking tutorial, but I'm having some trouble with the "bullets".
Each bullet prefab is spawned on the server-side through a command, according to the position of a spawn point on the player prefab. The basic system works well, but for all players except the host there is a large amount of lag between the location of the spawn point and the spawned bullet.
The bullets are spawned correctly according to the player's location on the server, as expected. However, this is behind the player's client position.
Is there a solution to this? Should I be using RigidBody at all? I've seen methods which use raycasting for projectiles which may be an improvement, but I would like to be able to see the projectiles travel through the air. Any help would be very appreciated!
For reference, the relevant PlayerController code:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class PlayerController : NetworkBehaviour {
public float speed;
public float turnSpeed;
public GameObject bulletPrefab;
public Transform bulletSpawn;
void Update () {
if (!isLocalPlayer) {
return;
}
float power = Input.GetAxis ("Vertical") * Time.deltaTime * speed;
float turn = Input.GetAxis ("Horizontal") * Time.deltaTime * turnSpeed;
transform.Rotate(0, turn, 0);
transform.Translate (power, 0, 0);
if (Input.GetKeyDown (KeyCode.Space)) {
CmdFire ();
}
}
[Command]
void CmdFire() {
var bullet = (GameObject)Instantiate (bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;
NetworkServer.Spawn (bullet);
Destroy (bullet, 2.0f);
}
}
I am trying to practice making third person controllers in Unity 3D. I am a beginner, and I am completely baffled on how to make my controller functional. I have been doing hours of research, but no thread I can find seem to answer my question. I have two scripts, a CameraController, and a CharacterController. My code is below.
CameraController:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public GameObject target;
public float rotationSpeed;
Vector3 offset;
Vector3 CameraDestination;
// Use this for initialization
void Start () {
offset = transform.position - target.transform.position;
CameraDestination = offset + transform.position;
rotationSpeed = 50f;
transform.position = CameraDestination;
}
// Update is called once per frame
void Update () {
transform.LookAt (target.transform.position);
float h = Input.GetAxisRaw ("Horizontal");
transform.RotateAround (target.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
target.transform.Rotate (0f, Time.deltaTime * h * rotationSpeed, 0f);
}
}
CharacterController:
using UnityEngine;
using System.Collections;
public class CharController : MonoBehaviour {
public float playerSpeed = 10f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float Vertical = Input.GetAxis("Vertical");
transform.position += transform.forward * Time.deltaTime * playerSpeed * Vertical;
}
}
When either the left or right arrow key is pressed, both the player and the camera rotates. If I try to attach the camera to the player as a children, the camera's rotation becomes messed up, but if I do not attach the camera to the player, the camera stops following the player. If I try to set the camera to a specific position relative to the player, it stops revolving around the player like it is intended to do. I simply can not come up with a method that works.Thank you for answering my question in advance!
When I go about this, I like to have an empty gameObject which has 2 children, the camera and then the mesh of the character.
> CharacterController
> Camera
> CharacterRig
When you want to rotate the character, rotate the CharacterController, then when you want to rotate the Camera around the character, change your code to:
transform.RotateAround (CharacterRig.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
This will allow your camera to rotate irrespective of any character animation and should solve your issue. This is very important if you want to implement animations later, as you don't want to parent the camera to the thing that is being animated because it will move with the animation.
P.s. Your code appears fine. Certain that it is purely the way you have set up the game objects.
So I got this code to instantiate my gameobject Cannon, witch has a child "ball" attached to it. I'm trying to rotate the "ball" around the "cannon" when I use my left/right arrow keys.
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
public GameObject Cannon = null;
public float speed = 1.0f;
void Start () {
Cannon = Instantiate (Resources.Load ("Prefabs/Cannon")) as GameObject;
}
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.LeftArrow)){
Cannon.transform.Rotate(Vector3.left * speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.RightArrow)){
Cannon.transform.Rotate(Vector3.right * speed * Time.deltaTime);
}
}
}
There is no Vector3.left, that would be an inverse of Vector3.right so you would just write that as "-Vector3.right". But regardless, you shouldnt be passing the vector3 of the direction you want to rotate in, but the axis in which you want to rotate around. in this case, you would use Vector3.up for both arguments, and use "* speed" for one, and "* -speed" for the other.