Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to move object A towards object B

Discussion in 'Physics' started by paperbagz, Feb 21, 2016.

  1. paperbagz

    paperbagz

    Joined:
    Feb 21, 2016
    Posts:
    4
    I'm trying to get it so that a object A will move at a constant speed towards an object B. The object 'B' is in the centre of the screen, and I want it to be so that if object A is below, to the right, above or to the left of object B, it will still move towards it. Basically I want object B to act as the 'centre of gravity' so that no matter where object A is, it will be attracted towards object B. Can't figure out how to do this.
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    A.transform.positon - b.transform.position, this will give you a vector, call it direction, then direction.normalize() * speed will give you a vector that you should put into a rigidbody velocity
     
    Ahlywog likes this.
  3. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    And do this in FixedUpdate and multiply speed by Time.fixedDeltaTime.
     
  4. paperbagz

    paperbagz

    Joined:
    Feb 21, 2016
    Posts:
    4
    Thanks for help guys, I manged to come up with :

    Code (CSharp):
    1. public class Attraction : MonoBehaviour
    2. {
    3.  
    4.     public float speed;
    5.     public GameObject Player;
    6.     public GameObject EnemyB;
    7.     public Rigidbody2D RB;
    8.  
    9.  
    10.     // Use this for initialization
    11.     void Start()
    12.     {
    13.  
    14.         speed = speed * Time.fixedDeltaTime;
    15.         RB = GetComponent<Rigidbody2D>();
    16.         Player = GameObject.FindWithTag("Player");
    17.         EnemyB = GameObject.FindWithTag("Enemy");
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void FixedUpdate()
    22.     {
    23.  
    24.         Vector2 direction = Player.transform.position - EnemyB.transform.position;
    25.         Vector2 newvector = direction.Normalize * speed;
    26.         RB.velocity = newvector;
    27.  
    28.  
    29.     }
    30. }
    All of it works as intended except for the 2nd last line, for 'direction.normalize * speed'. It won't let me normalize the speed, coming up with the error " Operator '*' cannot be applied to operands of type 'method group' and 'float'.
     
  5. paperbagz

    paperbagz

    Joined:
    Feb 21, 2016
    Posts:
    4
    Nevermind figured that one out also, but I have a new problem that when I instantiate a new enemy, or 'object A', it doesn't take the speed that I change via the interface. Only the enemies that are in the scene before the game is started have the speed set using the public float. The ones that are instantiated using this script :
    Code (CSharp):
    1. public class EnemyManager : MonoBehaviour
    2. {
    3.     public GameObject enemy;                // The enemy prefab to be spawned.
    4.     public float spawnTime = 3f;            // How long between each spawn.
    5.     public Transform[] spawnPoints;         // An array of the spawn points this enemy can spawn from.
    6.  
    7.  
    8.     void Start()
    9.     {
    10.         // Call the Spawn function after a delay of the spawnTime and then continue to call after the same amount of time.
    11.         InvokeRepeating("Spawn", spawnTime, spawnTime);
    12.     }
    13.  
    14.  
    15.     void Spawn()
    16.     {
    17.    
    18.  
    19.         // Find a random index between zero and one less than the number of spawn points.
    20.         int spawnPointIndex = Random.Range(0, spawnPoints.Length);
    21.  
    22.         // Create an instance of the enemy prefab at the randomly selected spawn point's position and rotation.
    23.         Instantiate(enemy, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
    24.     }
    25. }
    26.  
    all have a speed of 4, even if I set the public float to something like 300. How do I fix this?
     
  6. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    deltaTime and fixedDeltaTime tell you how much time elapsed between frames. Outside of Update, FixedUpdate, and LateUpdate I don't think it's reliable -- a given method might be called more than once per frame, or in the case of your Start it might be called before there are any frames.

    Even if it's reliable outside the various Update routines, I don't think you should be using it there at all. If I understand what you're trying to do, Start should just apply the full speed value. The delta values represent a fraction of a second (dump it to Debug.Log in Start), so you're only applying part of your total speed figure.

    A correct use of the delta value would be in one of the Update routines to simulate a change in speed over time. So if, for example, you start at 0 and want your speed to smoothly increase to some topSpeed, then you might do something like this:

    Code (csharp):
    1.  if(speed < topSpeed) speed += accelerationRate * Time.deltaTime;
    That way deltaTime ensures a uniform increase per frame, regardless of how much processing time each individual frame requires.
     
  7. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    It's not how that works, "public" means, it's accessible form other scripts
     
  8. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    I think he meant he set the speed in the Inspector view.
     
  9. paperbagz

    paperbagz

    Joined:
    Feb 21, 2016
    Posts:
    4
    Yeah, I set the speed in the inspector. I don't want the instantiated objects to start at a low speed and accelerate to the value I set in the inspector though, rather I want them to instantiate with the speed set in the inspector. I'm not sure why the scripts above don't do that.
     
  10. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    I misinterpreted the intent of your code while skimming it the other day. Sorry, I was at the office and was distracted.

    Your existing Update code will already assign maximum velocity as long as you remove the speed change in Start. If you always want your objects moving at maximum speed, then that's all you need to change.

    The problem is that you're multiplying the target speed in Start by a delta, and that's not good for the reasons I explained earlier. Delta can change on each and every frame (that's the whole point of it), so reference that inside Update if you want to change a speed or scale some other effect over time. Multiplying it once in Start just means you've randomly and permanently reduced the speed value to some fraction of the Inspector setting based on however much time has elapsed since the last frame.

    Or in concrete terms, if your speed value was set to 300, and the game was running at 60 FPS, a frame might take (for the sake of example) 0.025 seconds, so 0.025 is what would be stored in deltaTime after that frame. So in that case your speed would be changed to just 300 * 0.025 = 7.5 -- and it would remain 7.5 since you only change it one time in Start. I don't think you need to scale speed by a delta in this code at all, but doing it in Start is definitely not what you want.

    If you want to simulate a change over time that is smoothly stepped with the frame rate, then you'd use deltaTime in Update (or fixedDeltaTime in FixedUpdate) on each and every frame. You could create a public float for accelerate or decelerate, for example. It would be expressed as a rate of change per second, so you'd multiply the acceleration rate or deceleration rate by delta on each and every frame (because delta can change), then multiply that by the velocity vector to speed up or slow down. Obviously you'd also have to add tests to ensure you didn't exceed a maximum speed or slow down too much.

    Another option is to just update positions directly if you don't absolutely need to use physics. It can sometimes be difficult to get the desired behavior by applying forces to the various Rigidbody parameters.
     
  11. Dieter_Dagger

    Dieter_Dagger

    Joined:
    May 16, 2020
    Posts:
    4
    Wish you posted your solution other than, "Never mind, I figured that one out." Your post is meant to help readers for years, not solve your individual problem.
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,372
    It was also over 7 years ago so you necro'd a post to complain to a user who made 4 posts.