- Home /
(2D) Need Object Moving with AddForce to Change Direction
So I need a player object that is under the effects of AddForce to move from one waypoint to the next to make a sharp directional change with no loss of momentum. Is there a way to do this? Right now I have it so the player stops when they reach the next waypoint (because the alternative seems to be that the player flies off the rails completely.) Here is the code I have for an object changing to the next waypoint.
Under Update...
if (Mathf.Abs (Nodes[Node2].transform.position.y - transform.position.y) < 0.1 && Mathf.Abs (Nodes[Node2].transform.position.x - transform.position.x) < 0.1) {
if (Railroad == true){ //Whether or not player is on rails
if (IsNearNode == true){ //Is Player inside of the next node
if (Node < NodesNumber){ //Is this NOT the last node in sequence
Node = Node + 1; //Move to next waypoint
//rigidbody2D.velocity = dir;
rigidbody2D.velocity = Vector2.zero; //I know this is here
IsNearNode = false; //force current waypoint to no longer function for as long as player is in proximity
IsAtExit = false; //Definitionally prevents player from accidentally being at exit
}
else if (Node == NodesNumber){ //If player is at last waypoint in sequence...
IsAtExit = true;
}
}
}
}
else if (Mathf.Abs (Nodes [Node].transform.position.y - transform.position.y) < 0.1 && Mathf.Abs (Nodes [Node].transform.position.x - transform.position.x) < 0.1) { //The same thing as above but for going backwards.
if (Railroad == true){
if (Node > 0){
if (IsNearNode == true){
IsNearNode = false;
//rigidbody2D.velocity = dir;
rigidbody2D.velocity = Vector2.zero;
Node = Node - 1;
IsAtExit = false;
}
}
else if (Node == 0){
IsAtExit = true;
}
}
}
Answer by robertbu · Oct 13, 2014 at 07:13 PM
The concept is to capture the current speed, then multiply it by the normalized new direction.
rigidbody2D.velocity = rigidbody2D.velocity.magnitude * dir.normalized;
Where 'dir' is your new direction.
Just causes the player to fishtail off the rails without a significant direction change.
I need to see the code. Look for something else impacting the direction. Verify that 'dir' is pointing in the new direction. Use Debug.DrawRay(). Verify this line by testing in a simple app outside of your waypoint code. Used correctly, it will change the direction without loosing the speed.
Answer by EmpI · Oct 14, 2014 at 12:22 AM
using UnityEngine; using System.Collections;
public class PlayerMovement : MonoBehaviour{
private float movement = 1.3f;
private int Node = 0;
private int Node2 = 0;
public GameObject[] Nodes;
public GameObject DeathScreen;
public bool Railroad = false;
private bool canleave = true;
private bool toggle = true;
private bool IsNearNode = false;
private Vector2 dir = new Vector2();
private Vector2 dir2 = new Vector2();
private int NodesNumber;
private bool IsAtExit = false;
public bool Dying = false;
private int dyingtimer = 0;
void Start(){
NodesNumber = Nodes.Length - 3;
if (Railroad == true) {
canleave = false;
}
}
void Update(){
//Player Death
if (Dying == true){
dyingtimer = dyingtimer + 1;
renderer.enabled = false;
rigidbody2D.velocity = Vector2.zero;
collider2D.enabled = false;
Destroy (GameObject.Find ("3D Collider"));
Destroy (GameObject.Find ("2DCollider"));
Destroy (GameObject.Find ("RotTest"));
Destroy (GameObject.Find ("PlayerGlow"));
if (dyingtimer == 2){
Instantiate (DeathScreen, new Vector3 (transform.position.x, transform.position.y, -8.5f), transform.rotation);
}
}
Node2 = Node + 1;
dir = Nodes[Node2].transform.position - transform.position;
dir = dir.normalized;
dir2 = Nodes[Node].transform.position - transform.position;
dir2 = dir2.normalized;
if (Railroad == false) {
IsAtExit = false;
}
if (IsNearNode == false) {
IsAtExit = false;
}
if (canleave == false) {
IsAtExit = false;
}
//Checks if Player is below Node 1
if (Railroad == true)
{
if (transform.position.y < Nodes[Node].transform.position.y)
{
if (IsAtExit == true){ //stops player
rigidbody2D.velocity = Vector2.zero;
transform.position = Nodes[Node].transform.position;
}
}
if (transform.position.y > Nodes[Node2].transform.position.y)
{
if (IsAtExit == true){ //stops player
rigidbody2D.velocity = Vector2.zero;
transform.position = Nodes[Node2].transform.position;
}
}
}
Movement();
if (Input.GetKey (KeyCode.M)) {
if (toggle == true) {
if (Railroad == true) {
if (IsAtExit == true){
Railroad = false;
}
}
else if (Railroad == false) {
if (IsNearNode == true){
Railroad = true;
if (Node == NodesNumber){
transform.position = Nodes[Node2].transform.position;
}
else if (Node == 0){
transform.position = Nodes[Node].transform.position;
}
}
}
}
toggle = false;
}
if (Input.GetKeyUp (KeyCode.M))
{
toggle = true;
}
//Switch to next node
if (Mathf.Abs (Nodes[Node2].transform.position.y - transform.position.y) < 0.1 && Mathf.Abs (Nodes[Node2].transform.position.x - transform.position.x) < 0.1) {
if (Railroad == true){
if (IsNearNode == true){
if (Node < NodesNumber){
Node = Node + 1;
//rigidbody2D.velocity = dir;
//rigidbody2D.velocity = Vector2.zero;
rigidbody2D.velocity = rigidbody2D.velocity.magnitude * dir;
IsNearNode = false;
IsAtExit = false;
}
else if (Node == NodesNumber){
IsAtExit = true;
}
}
}
}
else if (Mathf.Abs (Nodes [Node].transform.position.y - transform.position.y) < 0.1 && Mathf.Abs (Nodes [Node].transform.position.x - transform.position.x) < 0.1) {
if (Railroad == true){
if (Node > 0){
if (IsNearNode == true){
IsNearNode = false;
//rigidbody2D.velocity = dir;
//rigidbody2D.velocity = Vector2.zero;
rigidbody2D.velocity = rigidbody2D.velocity.magnitude * dir2;
Node = Node - 1;
IsAtExit = false;
}
}
else if (Node == 0){
IsAtExit = true;
}
}
}
}
void Movement (){
if (Railroad == false) {
if (Input.GetKey (KeyCode.D)) {
rigidbody2D.AddForce (Vector2.right * movement);
}
if (Input.GetKey (KeyCode.A)) {
rigidbody2D.AddForce (Vector2.right * -movement);
}
if (Input.GetKey (KeyCode.W)) {
rigidbody2D.AddForce (Vector2.up * movement);
}
if (Input.GetKey (KeyCode.S)) {
rigidbody2D.AddForce (Vector2.up * -movement);
}
}
//railroad movement
else if (Railroad == true) {
if (Input.GetKey (KeyCode.D)) {
if (Nodes[Node2].transform.position.x > Nodes[Node].transform.position.x){
rigidbody2D.AddForce (dir * movement);
}
else if (Nodes[Node2].transform.position.x < Nodes[Node].transform.position.x){
rigidbody2D.AddForce (dir2 * movement);
}
}
else if (Input.GetKey (KeyCode.A)) {
if (Nodes[Node2].transform.position.x < Nodes[Node].transform.position.x){
rigidbody2D.AddForce (dir * movement);
}
else if (Nodes[Node2].transform.position.x > Nodes[Node].transform.position.x){
rigidbody2D.AddForce (dir2 * movement);
}
}
else if (Input.GetKey (KeyCode.W)) {
if (Nodes[Node2].transform.position.y > Nodes[Node].transform.position.y){
rigidbody2D.AddForce (dir * movement);
}
else if (Nodes[Node2].transform.position.y < Nodes[Node].transform.position.y){
rigidbody2D.AddForce (dir2 * movement);
}
}
else if (Input.GetKey (KeyCode.S)) {
if (Nodes[Node2].transform.position.y < Nodes[Node].transform.position.y){
rigidbody2D.AddForce (dir * movement);
}
else if (Nodes[Node2].transform.position.y > Nodes[Node].transform.position.y){
rigidbody2D.AddForce (dir2 * movement);
}
}
}
}
void OnTriggerEnter2D (Collider2D NodeS){
if (NodeS.gameObject.tag == "Node1") {
IsNearNode = true;
}
}
void OnTriggerExit2D (Collider2D Node){
if (Node.gameObject.tag == "Node1"){
IsNearNode = false;
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613165022im_/https://answers.unity.com/themes/thub/images/avi.jpg)