- Home /
Why is my Vector2.MoveTowards() not moving towards the player?
I'm making a 2d bullet hell game. I'm trying to get a ball to launch towards the direction of the player(triangle) when it spawns. The player can be anywhere. However the Vector2.MoveTowards always sets the vector to move away from the middle of the fixed screen. Not away from the player, not towards the player(What I want). Whats going on, how can I fix, and tips for future use?
I am only using two scripts.
BallController.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class BallController : MonoBehaviour
{
Rigidbody2D rigidbody2d;
TriangleController triangleController;
float lifeTime = 10;
Vector2 trianglePosition;
void Start()
{
trianglePosition = GameObject.Find("Triangle").GetComponent<Rigidbody2D>().position;
rigidbody2d = GetComponent<Rigidbody2D>();
Vector2 TowardsPlayer = Vector2.MoveTowards(rigidbody2d.position, trianglePosition, 1.0f);
rigidbody2d.AddForce(TowardsPlayer);
Debug.Log("Triangle pos = " + trianglePosition + " " + "Ball position = " + rigidbody2d.position + " " + "Towards player =" + TowardsPlayer);
}
// Update is called once per frame
void Update()
{
lifeTime -= Time.deltaTime;
if (lifeTime <= 0)
{
Debug.Log("Ball life time reached");
Destroy(gameObject);
}
}
/*
public void Launch(Vector2 force)//float x, float y)
{
rigidbody2d.AddForce(force);
}
*/
/*
Vector2 toPlayer(Vector2 ballPosition) //find the X and Y difference to palyer for force vector
{
Vector2 playerPosition = rigidbody2d.position;
float diffInX = playerPosition.x - ballPosition.x;
float diffInY = playerPosition.y - ballPosition.y;
Vector2 vectorToPlayer = new Vector2(diffInX, diffInY);
return vectorToPlayer;
}
*/
void OnTriggerEnter2D(Collider2D other)
{
TriangleController player = other.gameObject.GetComponent<TriangleController>();
//Debug.Log("Ive entered a ball");
if (player != null)
{
Debug.Log("Ive hit a player");
player.ChangeHealth(-1);
}
//Debug.Log("Ball destroyed");
Destroy(gameObject);
}
}
TriangleController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriangleController : MonoBehaviour
{
public float speed = 1;
Rigidbody2D rigidbody2d;
int maxHealth = 3;
//public int health { get { return currentHealth; } } //use this for health collectable
int currentHealth;
float currentTime;
float ballSpawnTime = 2.0f; //ball spawn cooldown = 2 seconds
public GameObject ballSprite;
BallController ball;
void Start()
{
//set health && get ridgidbody ready for movement
rigidbody2d = GetComponent<Rigidbody2D>();
ball = GetComponent<BallController>();
currentHealth = maxHealth;
}
void Update()
{
//movement
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical); //vector2 for new movement
Vector2 position = rigidbody2d.position;
position = position + move * speed;
rigidbody2d.MovePosition(position);
//spawn new balls with respect to the timer
ballSpawnTime -= Time.deltaTime;
if (ballSpawnTime <= 0)
{
switch (Random.Range(0, 7))
{
case (0)://top of screen left
Debug.Log("Enter case 0");
spawnBall(Random.Range(-9.4f,0.0f), 4.5f);
break;
case (1)://top of screen right
Debug.Log("Enter case 1");
spawnBall(Random.Range(0.0f, 9.4f), 4.5f);
break;
case (2)://right of screen top
Debug.Log("Enter case 2");
spawnBall(9.4f, Random.Range(0.0f, 4.5f));
break;
case (3)://right of screen bot
Debug.Log("Enter case 3");
spawnBall(9.4f, Random.Range(-4.5f, 0.0f));
break;
case (4)://bot of screen right
Debug.Log("Enter case 4");
spawnBall(Random.Range(0.0f, 9.4f), -4.5f);
break;
case (5)://bot of screen left
Debug.Log("Enter case 5");
spawnBall(Random.Range(-9.4f, 0.0f), -4.5f);
break;
case (6)://left of screen bot
Debug.Log("Enter case 6");
spawnBall(-9.4f, Random.Range(-4.5f, 0.0f));
break;
case (7)://left of screen top
Debug.Log("Enter case 7");
spawnBall(-9.4f, Random.Range(0.0f, 4.5f));
break;
}
ballSpawnTime = 2;//reset cooldown
}
}
void spawnBall(float locationX, float locationY) //this spawns a ball at where you want it
{
Vector2 spawn = new Vector2(locationX, locationY);
GameObject projectileObject = Instantiate(ballSprite, spawn, Quaternion.identity);
}
public void ChangeHealth(int amount)
{
if (amount < 0) //Take Damage
{
//if (isInvincible)
//{
//return;
//}
//isInvincible = true;
//invincibleTimer = timeInvincible;
//animator.SetTrigger("Hit");
}
else if (amount > 0)//heal
{
//Debug.Log("Pretend this is a heal animation");
//healEffect.Play();
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
//UIHealthBar.instance.SetValue(currentHealth / (float)maxHealth);
Debug.Log(currentHealth + "/" + maxHealth);
}
}
Answer by Lukas-Wendt · Nov 06, 2019 at 04:21 PM
MoveTowards is used to move a point towards a target by the maxDistanceDelta, so it's not giving you a direction, but a new point.
If you want to add a force to the ball in the direction of the player, you can get the direction by calculating (to - from) and normalizing the result.
It could look something like this:
Vector2 direction = (trianglePosition - rigidbody2d.position).normalized;
rigidbody2d.AddForce(direction);
To control the speed, you can multiply the direction by a factor.
float speed = 10;
rigidbody2d.AddForce(direction * speed);
Please note that AddForce's default mode is Force$$anonymous$$ode.Force, which divides the force by the mass and physics tickrate before applying it to the velocity. What you want here is Impulse or VelocityChange.