Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by tbngrd · Jul 29, 2018 at 01:29 PM · rigidbody2drigidbody.addforcerigidbody.velocitydashknockback

How to move Rigidbody2D on Player a certain amount at a certain speed, for a dash move and knockback?

Hi everyone.

Im currently having two problems for, I think, the same or similar reason. I'm working on a top-down game to learn Unity and C#. I have a PlayerController in which I'm using the Rigidbody2D's velocity to move the player.

I would like to implement a dash move, allowing the player to move a certain amount in any direction at a fixed speed, as well as a knockback when the player is hit, that should behave in a similar way: knocking back the player a certain amount, at a certain speed. I do not understand at all how to do this. Below is the code of my PlayerController, with both of these things sort of working, but not correctly. I'm pasting the whole code, I guess a lot of it is irrelevant to the problem, but I'm leaving it in in case it isn't.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerController : MonoBehaviour {
 
     //Speed Variables
     public float speed;
     public float walkSpeed;
     public float runSpeed;
 
     //Animation Variables
     private Animator anim;
     private bool PlayerMoving;
     public Vector2 lastMove;
     public float DirectionX;
     public float DirectionY;
 
     //Knockback Variables
     public float knockback;
     public float knockbackLength;
     public float knockbackCount;
     private Vector2 knockbackDirection;
 
     //Dash Variables
     [SerializeField] private float dashSpeed;
     public float dashCount;
     [SerializeField] private float startDashCount;
     private Vector2 dashOGpos;
 
     private Rigidbody2D rb2d;
 
     private Vector2 movement;
 
     [SerializeField] private float timeBetweenDamage;
     [SerializeField] private float startTimeBetweenDamage;
 
     void Start ()
     {
         rb2d = GetComponent<Rigidbody2D>();
         anim = GetComponent<Animator> ();
         knockbackCount = 0;
     }
 
     void FixedUpdate()
     {
         PlayerMoving = false;
 
         float moveHorizontal = Input.GetAxisRaw ("Horizontal");
         float moveVertical = Input.GetAxisRaw ("Vertical");
 
         if(knockbackCount <=0)
         {
         //Movement via Rigibody veloctiy:
         movement = new Vector2(moveHorizontal, moveVertical);
         rb2d.velocity = movement * speed * Time.deltaTime;
         } else{
             Debug.Log("Should knock back");
             //transform.Translate(knockbackDirection * knockback * Time.deltaTime);
             //rb2d.AddForce(knockbackDirection * knockback * Time.deltaTime, ForceMode2D.Impulse);
             rb2d.velocity = knockbackDirection * knockback * Time.deltaTime;
 
             knockbackCount -= Time.deltaTime;}

The part above handles the player's general movement as well as the Knockback. It sort of works, but the main problem I have with it, it only does when I set the float knockback to an exorbitantly high. If I set it to 1000 for example, the player gets knocked back a way too big distance, but at a speed that's too slow. If I set it to like 4000 the speed is better, but the distance of course is even bigger. What I want is movement at a short distance, at high speed. The Vector2 knockbackDirection is being set in a function further below, this works as intended. As you can see I'm currently doing it by manipulating the Rigidbody2D's velocity, however I tried it as well with AddForce or even manipulating the object's transform directly (which isn't a good idea I guess).

 //Running via Spacebar, or 0
         if (Input.GetKey ("space"))
         {
             speed = runSpeed;    
         } else
             {
                 speed = walkSpeed;
             }

This little part above changes my character's speed by pressing space, in order to run. This works fine.

 //DASH
         if(dashCount <= 0f)
             {
                 if(Input.GetKey("x"))
                 {
                     Debug.Log("ShouldDash");
                     dashCount = startDashCount;
                     rb2d.velocity = movement * dashSpeed * Time.deltaTime;
                 }
             } else
                 dashCount -= Time.deltaTime;

Now here's the dash part above that I'm having trouble with. Again, like the knockback, this kind of works, but not nearly as well as I like it too. Again, I have to set dashSpeed to a similarly high amount like with the knockback. If I set it to 1000 the player dashes a tiny distance but way too fast. If I increase it to 5000, the distance is closer to what I want, but of course, it's way too fast.

 //Animation NEW
         if (Input.GetAxisRaw ("Horizontal") > 0.01f || Input.GetAxisRaw ("Horizontal") < -0.01f)
         {
             PlayerMoving = true;
             lastMove = new Vector2 (Input.GetAxisRaw ("Horizontal"), 0f);
         }
         if (Input.GetAxisRaw ("Vertical") > 0.01f || Input.GetAxisRaw ("Vertical") < -0.01f)
         {
             PlayerMoving = true;
             lastMove = new Vector2 (0f, Input.GetAxisRaw ("Vertical"));
         }
                 anim.SetFloat("MoveX", Input.GetAxisRaw("Horizontal"));
                 anim.SetFloat ("MoveY", Input.GetAxisRaw ("Vertical"));
                 anim.SetBool ("PlayerMoving", PlayerMoving);
                 anim.SetFloat ("LastMoveX", lastMove.x);
                 anim.SetFloat ("LastMoveY", lastMove.y);
     }
 
     void Update()
     {
         if(timeBetweenDamage >= 0)
             timeBetweenDamage -= Time.deltaTime;
     }
     void LateUpdate ()
     {
             DirectionX = Input.GetAxisRaw("Horizontal");
             DirectionY = Input.GetAxisRaw("Vertical");
     }
 
     void OnTriggerEnter2D (Collider2D other) //Detect Collisons with Enemies etc.
     {
         Debug.Log("Got hit");
         if(timeBetweenDamage <= 0)
         {
             if(other.gameObject.CompareTag("Enemy"))
             {
                 this.GetComponent<PlayerHealthManager>().HurtPlayer(other.GetComponent<HurtPlayer>().damageToGive);
                 this.knockbackCount = this.knockbackLength;
                 other.GetComponent<Transform>();
 
                 knockbackDirection = (transform.position - other.transform.position).normalized;
 
                 Debug.Log("knockbackDir:" + knockbackDirection);
 
                 timeBetweenDamage = startTimeBetweenDamage; 
                 
             }
         }
     }
 }

Above the rest of the code. The last function, that checks for collisions with enemies also sets the knockbackDirection Vector2 used for the knockback, as well as resets the knockbackCount.

I apologize for the kind of messy code, I'm a total beginner and I'm trying to make things work by watching tutorials, trial and error and googling my way around.

I guess what I need for both of those things is a way to move my player a certain amount, at a certain speed and I have no idea hot to do it. I've experimented with Rigidbody2D.MovePosition and/or Vector2.MoveTowards with no success.

Does anybody have an idea how to go about this? I'd really appreciate it any tip whatsoever.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Knightsurfer · Jul 29, 2018 at 06:42 PM

I much tidier way to do the run thing would be:

 speed = Input.GetKey(KeyCode.Space) ? runSpeed : walkSpeed;

As for the being pushed back, I guess you could have something along the lines of:

 float knockbackamount = transform.position.z - 10;
 if (transform.position.z != knockbackamount)
 {
 transform.translate(0,0,-speed);
 }

mind you this is just off the top of my head and I haven't tested it, so you would have to tinker around. if it does work then a similar principle would work for dash too.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by tbngrd · Jul 29, 2018 at 11:32 PM

@Knightsurfer Thanks a lot for the tips!

I meanwhile figured out a way to do what I wanted. There was a logical error, I wasn't manipulating the velocity at the right place. For the dash, I now set the velocity inside another if statement checking if the dashCount is over 0, so the speed change is valid for the whole time dashCount is counting down. That allows me to tweak the distance/speed by setting dashSpeed and startDashCount;

 //DASH
         if(dashCount <= 0f ) 
             { 
                 if(Input.GetKeyDown("x"))
                 {   dashCount = startDashCount; //set dash counter when pressing button
 
                     Debug.Log("ShouldDash");    
                 }                
             } else
                 dashCount -= Time.deltaTime; //count town dash counter after dash
 
         if(dashCount > 0f) // while dash counter is over zero move at dash speed
             {
                 rb2d.velocity = movement * dashSpeed * Time.deltaTime;    
             }

For the knockback, I did it in a similar way, but I put it in a separate function to call on collisions (where the timer variable knockBackCount is being set as well).

     void knockBack()
     {
             Debug.Log("Knockback Direction: " + knockbackDirection);
             Debug.Log("Should knock back");
                         if(knockbackCount > 0){
             rb2d.velocity = knockbackDirection * knockback * Time.deltaTime;
             }
     }

Both things are working exactly like I wanted now. I quite like how it feels with setting the velocity directly, but I guess now that it works I will also experiment with AddForce.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

90 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Jumping problems (how to stop a force) 1 Answer

Air-Dash phases through walls due to high velocity? 0 Answers

How can i initiate an object in parabolic motion without using gravity using Rigidbody2D? 0 Answers

Do rigid bodies with force add force to other objects? 0 Answers

How can i initiate an object in parabolic motion without using gravity using Rigidbody2D? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges