Unity 5: How to slow down rigidbody naturally instead of sudden stop - c#

I'm using this:
void Update(){
if(leftJoystick){
rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse);
}
}
to move my character forward in the air (using jetpack). When I let go of the joystick my character stops immediately. What I want is that the character keeps moving forward after joystick is released and with time slow down and gradually stop. It looks stupid that my character stops like it hit a wall. What kind of force/velocity/transform I should use so that physics slow down my character after I let go of the joystick?
My rigidbody settings:
Mass: 100
Drag: 0
Angular drag: 0.05
Uses gravity
Not kinematic
Interpolate: interpolate
Collision detection: Discrete
Freeze position: none
Freeze rotation: all
Character also has a capsule collider that is NOT trigger and has no physics material.
EDIT: here is the full code so you can see if there is any conflicts in my code
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class JetpackController : MonoBehaviour{
Rigidbody rb;
// controller axes
[SerializeField]
public string speedAxis = "Vertical";
public string rotateAxis = "HorizontalRotate";
[SerializeField]
public float forwardSpeed;
public float upSpeed;
public float rotateSpeed;
public float rotationIgnoreZone;
public float MAX_HEIGHT;
float speedInput;
float rotateInput;
public bool leftJoystick;
public bool rightJoystick;
ParticleSystem jetpackFire1;
Vector3 originalGravity;
// access Joystick script in Standard assets to detect when right joystick is held down
Joystick joystick_left;
Joystick joystick_right;
void Start () {
if (GetComponent<Rigidbody> ()) {
rb = GetComponent<Rigidbody> ();
} else {
Debug.LogError ("Player needs to have a rigidbody.");
}
// get Joysticks
if (GameObject.Find ("MobileJoystick_left").GetComponent<Joystick> ()) {
joystick_left = GameObject.Find ("MobileJoystick_left").GetComponent<Joystick> ();
} else {
Debug.LogError ("Either gameobject with name 'MobileJoystick_right' does not exist in the scene or it does not have script called Joystick.cs attached to it.");
}
if (GameObject.Find ("MobileJoystick_right").GetComponent<Joystick> ()) {
joystick_right = GameObject.Find ("MobileJoystick_right").GetComponent<Joystick> ();
} else {
Debug.LogError ("Either gameobject with name 'MobileJoystick_right' does not exist in the scene or it does not have script called Joystick.cs attached to it.");
}
jetpackFire1 = GameObject.Find("JetpackFire1").GetComponent<ParticleSystem> ();
jetpackFire1.playbackSpeed = 5.0f;
originalGravity = Physics.gravity;
}
void FixedUpdate () {
GetInput ();
// move forward and backward according to left joysticks input
if(leftJoystick){
// left joystick held down
rb.AddRelativeForce(0, 0, forwardSpeed*speedInput, ForceMode.Impulse);
}
// if right joystick is used
if (rightJoystick) {
jetpackFire1.Play ();
if (transform.position.y < MAX_HEIGHT) {
// allow going up
//rb.AddRelativeForce (0, upSpeed, 0, ForceMode.Impulse);
rb.AddForce(transform.forward * forwardSpeed);
} else if (transform.position.y >= MAX_HEIGHT) {
// prevent player to go any further up and also falling
Physics.gravity = Vector3.zero; // no gravity to prevent player from falling
rb.velocity = Vector3.zero;
}
// rotate
// always keep rotating (player can go past look at joystick dir)
if (rotateInput >= rotationIgnoreZone || rotateInput <= -rotationIgnoreZone) {
transform.Rotate(Vector3.up * rotateInput, Time.deltaTime * rotateSpeed);
}
} else {
jetpackFire1.Stop ();
// if right joystick is released
Physics.gravity = originalGravity; // normal gravity -> player can fall
}
}
public void GetInput(){
speedInput = CrossPlatformInputManager.GetAxis (speedAxis);
rotateInput = CrossPlatformInputManager.GetAxis (rotateAxis);
// access Joystick.cs script to grab wether right joystick is pressed or not
leftJoystick = joystick_left.leftJoystickPressed;
rightJoystick = joystick_right.rightJoystickPressed;
}
}

Can't comment yet
Like J.Small said, you could multiply the velocity with a number around 0.95 to slowly slow the rigidbody down. If you put the multiplication in the Update method I suggest you to multiply the ~0.95 number with Time.deltaTime, so the velocity decrease will be proportional to the passed time.
void Update(){
if(leftJoystick){
rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse);
}
if(noJoystick){
rb.velocity = rb.velocity * 0.95 * Time.deltaTime;
//Or: rb.velocity.x
}
}
You could also apply a small amount of force instead of multiplying the velocity if you want to slow down the rigidbody in a more configurable way (the amount should be based on Time.deltaTime if you put it into Update - which gets called once a frame), but the method above is easier.

I'm not a pro at coding, so I'm not sure if this'll work for everyone, but I tried something like this to fix a similar issue.
void FixedUpdate()
{
playerRigidbody.AddRelativeForce(Vector2.up * forwardInput * playerSpeed * Time.fixedDeltaTime);
if (forwardInput <= 0)
{
playerRigidbody.velocity = playerRigidbody.velocity / 1.005f; // <-- This will gradually slow down the player when they're idle.
}
}

You could do a simple linear slow down.
void Update(){
if(leftJoystick){
rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse);
}
if(noJoystick){
rb.velocity = rb.velocity * 0.9;
}
}
Note that the update function gets called on frame update, so I would suggest putting this in a FixedUpdate() function that way the slow rate won't depend on the frame rate.

Related

Unity2D move object up and back down with smooth transition

(I'm a beginner so please have patience with me).
How it needs to happend:
I have a player that can jump and hit a tile, on collision the tile with move a fixed distance up and come back down with a smooth transition.
What I have so far:
I am detecting the collision now there's only the matter of moving the tile up and down.
The catch
The tiles are suspended in air so basically they either don't have a RigidBody2D or they have one with gravity scale 0
What I've tried
Basically I've tried 2 solutions:
(I'm not limited to these 2, I want to implement the solution that is correct so I am open to other ideas)
I was thinking to simply take the current position, calculate another vector with another position, and lerp to the new position and then lerp back to the initial one.
Vector2 initialPosition = transform.position;
Vector2 targetPosition = new Vector2(initialPosition.x + 4f, initialPosition.y + 4f);
print("Initial position: " + initialPosition);
print("Target position: " + targetPosition);
Vector2.Lerp(initialPosition, targetPosition, 1f);
I tried adding a rigidbody with scale 0
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Ground")
{
Jumping = false;
anim.SetInteger("State", 0);
}
// print("Colision layer: " + collision.collider.gameObject.layer);
if (collision.collider.gameObject.layer == Mathf.Log(layerMask.value, 2))
{
GameObject Tile = collision.gameObject;
Rigidbody2D rigidBody = Tile.GetComponent<Rigidbody2D>();
rigidBody.gravityScale = 1;
rigidBody.AddForce(new Vector2(0, 10f), ForceMode2D.Force);
StartCoroutine(MoveTileWithForce(rigidBody));
}
}
IEnumerator MoveTileWithForce(Rigidbody2D TileRigidBody)
{
yield return new WaitForSeconds(1);
TileRigidBody.AddForce(new Vector2(0, -5f), ForceMode2D.Force);
TileRigidBody.gravityScale = 0;
print("END MY COROUTINE, gravityScale: " + TileRigidBody.gravityScale);
}
I think the best way you can achieve this is in this simple way:
1
Make sure you have a box collider for your character and a Rigidbody and the same for the block you wanna move. For both of the colliders set on trigger. If you want to have another collider for the player in order to make him touch the ground or hit enemies you can add another box collider, but make sure you have one on trigger on his head
2
Add a script to the block you wanna move and also a tag to the player, for example "player"
3
Inside of this new script check if the block is triggering the player:
void OnTriggerEnter2D(Collision other)
{
if(other.compareTag("player"))
{ StartCoroutine(MovingBlock(0.5f, transform.position, upperPosition));}
|
It will enter inside the if when the player touches the block, it will start a coroutine that I will now write so you will understand the 0.5f and the other variables
IEnumerator MovingBlock(float time, Vector2 startpos, Vector2 endpos)
{
float elapsedTime = 0;
while (elapsedTime < time)
{
transform.position= Vector2.Lerp(startpos, endpos, (elapsedTime / time));
elapsedTime += Time.deltaTime;
yield return null;
}
elapsedTime = 0f;
while (elapsedTime < time)
{
transform.position= Vector2.Lerp(endpos, startpos, (elapsedTime / time));
elapsedTime += Time.deltaTime;
yield return null;
}
}
Basically, the Coroutine will move the object from startpos to endpos and then back again in the amount of time that you decide (in this case 0.5 seconds). I have used the Vector2 variable upperposition and it's just the height you want to reach with the platform.
If you want, you can also add inside the coroutine some yield return new WaitForSeconds(timeToWait) and make the platform wait in a certain position the amount of seconds you want (timeToWait)
Declare Vector2 initialPosition at the beginning of your class.
On Start() of the tile object you should get the initialPosition = transform.position.
And in the OnCollisionEnter2D(Collision2D collision) you could start a coroutine to bring the tile back down.
So for example:
Player Script:
public class Player : MonoBehaviour
{
public Rigidbody2D rb;
//Initialize the rigidbody on the editor.
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(new Vector2(0f, 1000f));
}
}
}
And the tile script:
public class MyTile : MonoBehaviour
{
Vector2 initialPosition;
float speed = 2f; //the speed the tile will go down.
private void Start()
{
initialPosition = transform.position;
}
private void OnCollisionEnter2D(Collision2D collision)
{
//The amount you want to go up on the Y component, for this example I used 2.
transform.position = new Vector2(transform.position.x, transform.position.y + 2f);
StartCoroutine(MoveTileDown());
}
IEnumerator MoveTileDown()
{
while (transform.position.y > initialPosition.y)
{
transform.position = Vector2.Lerp(transform.position, initialPosition, Time.deltaTime * speed);
yield return null; //Make it run every frame, just like Update()
}
StopCoroutine(MoveTileDown());
}
}
There are a lot of ways you can achieve the same result, this is just one of them.

How can I apply scripts in new camera which is child of a gameobject

Earlier I was facing problem regarding the unity camera problem it always stuck on 0,0,0.08 and also find a solution so I first create an empty gameobject and then drag the camera in that empty gameobject but after doing this the scripts which I applied to the gameobject is working fine but the script which I place in camera is not working at all
Camera Script
public float MovementAmplitude = 0.1f;
public float MovementFrequency = 2.25f;
void Update()
{
transform.position = new Vector3(
transform.position.x,
Mathf.Cos(transform.position.z * MovementFrequency) * MovementAmplitude,
transform.position.z
);
}
Player Script
public float speed = 4.5f;
public float JumpingForcec = 450f;
void Update()
{
transform.position += speed * Vector3.forward * Time.deltaTime;
if (Input.GetKeyDown("space"))
{
Debug.Log("SPace is pressed");
Debug.Log(GetComponent<Rigidbody>());
GetComponent<Rigidbody>().AddForce(Vector3.up * JumpingForcec);
}
}
First of all when dealing with a Rigidbody (or the Physics in general) you shouldn't set a position directly through the Transform component but rather use Rigidbody.position or in your case for a smooth movement even rather Rigidbody.MovePosition, both in FixedUpdate.
In general anything related to the Physics (so also everything using Rigidbody) should be done in FixedUpdate while the check for GetKeyDown has to be done in Update.
PlayerScript
public class PlayerScript : MonoBehaviour
{
public float speed = 4.5f;
public float JumpingForcec = 450f;
// If possible reference this in the Inspector already
[SerializeField] private Rigidbody rigidBody;
private bool jumpWasPressed;
private void Awake()
{
if (!rigidBody) rigidBody = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
rigidBody.MovePosition(transform.position + speed * Vector3.forward * Time.deltaTime);
if (!jumpWasPressed) return;
Debug.Log("SPace was pressed");
rigidBody.AddForce(Vector3.up * JumpingForcec);
jumpWasPressed = false;
}
private void Update()
{
// Note that currently you can multijump .. later you will want to add
// an additional check if you already jump again
if (Input.GetKeyDown(KeyCode.Space)) jumpWasPressed = true;
}
}
Make sure that Is Kinematic is disabled in the Rigidbody component! Otherwise AddForce is not processed.
If isKinematic is enabled, Forces, collisions or joints will not affect the rigidbody anymore.
The camera movement I would move to LateUpdate in order to make sure it is the last thing calculated after the other Update calls have finished. Especially after all user input has been processed (in your case maybe not that relevant since movement is processed in FixedUpdate but in general).
Second problem: Here you are not taking the changed Y position by jumping into account so rather add the "wobbling" effect to the player's transform.position.y and rather use the localPosition for the Camera:
public class CameraScript : MonoBehaviour
{
public float MovementAmplitude = 0.1f;
public float MovementFrequency = 2.25f;
// reference the player object here
public Transform playerTransform;
private float originalLocalPosY;
private void Start()
{
if(!playerTransform) playerTransform = transform.parent;
originalLocalPosY = transform.localPosition.y;
}
private void LateUpdate()
{
transform.localPosition = Vector3.up * (originalLocalPosY + Mathf.Cos(playerTransform.position.z * MovementFrequency) * MovementAmplitude);
}
}
Maybe you want to disable the wobbling effect during a jump later, though ;)
Try to put all the update stuff in the same method, it should work both (theorically, not tested) so you have to fix your code in order to get what you want:
void Update() {
// Camera update
transform.position = new Vector3(
transform.position.x,
Mathf.Cos(transform.position.z * MovementFrequency) * MovementAmplitude,
transform.position.z
);
// Player update
transform.position += speed * Vector3.forward * Time.deltaTime;
if (Input.GetKeyDown("space"))
{
Debug.Log("SPace is pressed");
Debug.Log(GetComponent<Rigidbody>());
GetComponent<Rigidbody>().AddForce(Vector3.up * JumpingForcec);
}
}
Hope this helps you, cheers!

Unity crashes every time I try to stop the movement of my object

I'm making a non random generated runner game and I'm trying to code the boss entry and fight. So the game consist of an astronaut (player) that stays on screen all the time (so him, background and camera never move, well the player can move but it's clamped.
All the hazards come towards the player and he has to avoid them or defeat them until the last hazard which is the boss. The boss is at the end of the line and goes along the z-Axis as well towards the player and I want it to stop when it collides with a Quad, so the boss is static and they can fight.
After that I want the boss to move up and down and shoot the player with Lerp functions.
The code looks like this:
public class BossController : MonoBehaviour {
public float speed;
public float health;
public Animator anim;
public Transform startMarker;
public Transform endMarker;
private Rigidbody rb;
private HUDController hud;
private bool startIntro = false;
private float startTime;
private float journeyLength;
void Start () {
startTime = Time.time;
journeyLength = Vector3.Distance (startMarker.position, endMarker.position);
anim = GetComponent<Animator> ();
rb = GetComponent<Rigidbody> ();
rb.velocity = transform.forward * -speed;
}
void Update(){
//transform.position += transform.forward * -speed * Time.deltaTime;
if (startIntro) {
rb.velocity = new Vector3(0,0,0);
Fight ();
}
}
void Fight(){
float distCovered = (Time.time - startTime) * speed;
float fracJourney = distCovered / journeyLength;
while(true)
{
transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fracJourney);
transform.position = Vector3.Lerp(endMarker.position, startMarker.position, fracJourney);
}
}
void OnTriggerEnter(Collider other){
if (other.gameObject.CompareTag ("bossEntry")) {
startIntro = true;
//anim.SetTrigger ("quad");
}
}
}
I tried first with the rigidbody and when it collides, the rigidbody's velocity is 0 and that works fine AS LONG AS the Fight() method is commented. So maybe it's because of the lerp functions?
When it;s not commented when the boss hits the collider everything freezes and I cannot use Unity anymore and I have to restart the programm.
Please help!
Edit: I removed the while(true) loop and now the boss falls straight down when it collides with the quad instead of lerping. The Boss is under an empty object and both start and end markers are under the empty object as well. Every component is attached to the empty object (parent).
try and track (print) the values of your veriables.
I'd guess you have a divisor of 0 here -
float fracJourney = distCovered / journeyLength;
if not, its most likely you have an endless loop, or a null pointer which is vital.
Sorry, I just noticed this now.
transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fracJourney);
transform.position = Vector3.Lerp(endMarker.position, startMarker.position, fracJourney);
The second Lerp overrides the value of first one immediately. If you want something like a ping pong effect, make a flag to determine the current state you want.
bool toEndMarker = true;
void Fight() {
//Some code here
if(toEndMarker)
{
transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fracJourney);
if(//DETERMINE if transform.position is already at end marker)
{
toEndMarker = false;
}
}
else
{
transform.position = Vector3.Lerp(endMarker.position, startMarker.position, fracJourney);
if(//DETERMINE if transform.position is already at start marker)
{
toEndMarker = true;
}
}
}

Character won't jump in Unity2D but entered the jump statement

I have a little problem with my player control script (C#) in the unity enigne. I worked out the following script with the basic movement of the player. The problem is that the player can enter the jump statement (the debug log printed it out)
Debug Log
but it will not work. The character is still on the ground.
The jump function will be enabled when the player is on the ground (grounded) and did not a double jump.
So my question is are there any "code mistakes" or maybe some configuration problems which I do not see?
Thank you for your help in advance!
using UnityEngine;
using System.Collections;
public class PlayerControl : MonoBehaviour
{
// public variables
public float speed = 3f;
public float jumpHeight = 5f;
// private variables
Vector3 movement;
Animator anim;
Rigidbody2D playerRigidbody;
// variables for the ground check
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool grounded;
private bool doubleJump;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
// Proves if the player is on the ground and activate the double jump function
if (grounded)
{
doubleJump = false;
}
// First line of proving the jump
if (Input.GetMouseButtonDown(0) && grounded)
{
Debug.Log("Jump if entered");
Jump();
}
if (Input.GetMouseButtonDown(0) && !doubleJump && !grounded)
{
Debug.Log("double Jump");
Jump();
doubleJump = true;
}
// Flipping the Player when he runs back
if (Input.GetAxis("Horizontal") < 0)
{
playerRigidbody.transform.localScale = new Vector2(-1.7f, 1.7f);
}
else
{
playerRigidbody.transform.localScale = new Vector2(1.7f, 1.7f);
}
}
void Awake()
{
// References setting up
playerRigidbody = this.GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
// simple Movement without a speed control
Move(horizontal, vertical);
Animating(horizontal, vertical);
// Section for ground detection
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
// Set the parameter for the jump animation false or true
anim.SetBool("Grounded", grounded);
}
void Move(float horizontal, float vertical)
{
movement.Set(horizontal, 0f, vertical);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition(transform.position + movement);
}
void Jump()
{
playerRigidbody.AddForce(Vector3.up * jumpHeight);
// playerRigidbody.AddForce(new Vector2(0f, jumpHeight), ForceMode2D.Impulse);
Debug.Log("Jump function");
}
void Animating(float h, float v)
{
bool walking = h != 0f || v != 0f;
anim.SetBool("IsWalking", walking);
}
}
Just guessing here, but maybe Vector3.up does not work for 2D physics? I'm not really into 2D, but you could try
playerRigidbody.AddForce(transform.up * jumpHeight);
instead.
Also, have you tried different values for jumpHeight? 5 might be way to small depending on the mass you set for your rigidbody.
And make sure you haven't restricted any axes in the inspector.
// Note: If you want the object to move in a reliable predictable way but still allow physics interactions, use MovePosition (set the object to kinematic if you want it to be unaffected by physics but still be able to affect other things, and uncheck kinematic if you want both objects to be able to be acted on by physics.
If you want to move your object but let physics handle the finer details, add a force.
playerRigidbody.rigidbody2D.AddForce(Vector3.up * 10 * Time.deltaTime);
use Vector.up, Vector.down, vector.right, Vectore.left along with time.deltaTime to have smooth movement along the frame.

Shooting a ball (With gravity)

I am currently having trouble shooting a ball and adding velocity to it. The idea is that the longer you hold down "SPACE" the longer the ball will travel.
What I have so far is this for the player control:
public class PlayerControl : MonoBehaviour {
public float speed = 0f;
Vector3 enVector = new Vector3(10,0,0);
public bool laserDirection = false;
public Transform firePoint;
public GameObject RedBall;
public PlayerControl player;
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update ()
{
// Press CTRL to move the platform under the ball and shoot a laser (NOT FINISHED)
if (Input.GetKey (KeyCode.LeftControl) && laserDirection == false)
{
transform.Translate(enVector * -speed * Time.deltaTime);
}
else if(Input.GetKey (KeyCode.LeftControl) && laserDirection == true)
{
transform.Translate(enVector * speed * Time.deltaTime);
}
// Sets the direction the platform will travel if pressed
if(Input.GetKey (KeyCode.LeftArrow))
{
laserDirection = false;
}
// Sets the direction the platform will travel if pressed
if(Input.GetKey (KeyCode.RightArrow))
{
laserDirection = true;
}
// Shoots a ball the longer you hold down
if(Input.GetKey (KeyCode.Space))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (speed, GetComponent<Rigidbody2D> ().velocity.y);
Instantiate(RedBall, firePoint.position, firePoint.rotation);
}
}
// Destroy the ball
void OnTriggerEnter2D(Collider2D other)
{
Destroy (gameObject);
}
}
If you look where the get space button is you see the code I've made for the shooting. This only makes the ball travel to the right at a set speed I've chosen.
This is for changing the direction of the ball (It moves around the big black ball):
// THE DIRECTION OF THE BALL SCRIPT
public class RedBall : MonoBehaviour
{
public Transform target;
void Update()
{
// Moves the ball launcher to the left
if (Input.GetKey (KeyCode.LeftArrow))
{
transform.RotateAround (target.position, transform.forward, Time.deltaTime * 90f);
}
// Moves the ball launcher to the right
if (Input.GetKey (KeyCode.RightArrow))
{
transform.RotateAround (target.position, -transform.forward, Time.deltaTime * 90f);
}
}
}
I am struggling with how to figure out how to make the ball shoot in the direction it is facing, which depends on how it has been translated in the ball script. Additionally, how to make the ball react to the gravity when shot and how to shoot further the longer I hold hold the "SPACE" button.
If anyone knows how to do at least one of these things it would help a lot! Thank you.
(Instead of using Rigidbody2D.velocity try to use Rigidbody2D.AddForce. For turning gravity on and off use Rigidbody2D-gravityScale.
I'm not quite sure what you mean with "the longer I hold the "SPACE button". Do you want to make it a "Spring" and release it when the Space button was released?
edit:
maybe do it like this. make initial force a variable and "Load it" while the button is pressed, when it is release, instantiate the Ball and add the force to it.
i justed typed this out of the head, without testing so maybe it wont run out of the box, but the direction should be clear
if (Input.GetKey(KeyCode.Space))
{
initialForce += 0.1f;
GetComponent<Rigidbody2D>().velocity = new Vector2(speed, GetComponent<Rigidbody2D>().velocity.y);
Instantiate(RedBall, firePoint.position, firePoint.rotation);
}
else
{
if (initialForce > 0)
{
var ball = (GameObject)Instantiate(RedBall, firePoint.position, firePoint.rotation);
ball.GetComponent<Rigidbody2D>.AddForce(firePoint.rotation * Vector2.one * initialForce);
}
initialForce = 0f;
}
So I am struggling with how to figure out how to make the ball shoot
in the direction it is facing depending on how it have been translated
in the ball script.
Multiply speed by the direction you want to shoot in:
// Shoots a ball the longer you hold down
if(Input.GetKey (KeyCode.Space)) {
GetComponent<Rigidbody2D> ().AddForce(transform.forward * speed);
Instantiate(RedBall, firePoint.position, firePoint.rotation);
}
Also look into object pooling, you really shouldnt be instantiating projectiles it takes alot of memory to instantiate and destroy all the time during execution.
Also how to make the ball have the gravity when shot
protected float gravity = 1f;
protected bool isShot = false;
// Update is called once per frame
void Update ()
{
if(isShot)
rigidBody.velocity.z += gravity * Time.deltaTime;
}
shoot longer the longer I hold hold the "SPACE" button.
public float rate = 1.0f;
protected float power = 0f;
// Update is called once per frame
void Update ()
{
if (Input.GetKeyUp (KeyCode.Space))
{
UsePower(power);
power = 0f;
}
if (Input.GetKey (KeyCode.Space))
{
power += rate * Time.deltaTime;
}
}
void UsePower (float _power)
{
// Use power here
}

Categories