Search Unity

2D Point Effector only affects a single layer whereas multiple layers are selected

Discussion in 'Physics' started by farazk86, Sep 12, 2019.

  1. farazk86

    farazk86

    Joined:
    May 31, 2017
    Posts:
    195
    Hi,

    I wanted to create a blackhole like suction effect for my game that would suck in enemies and bullets. But what I came up with is very selective and chooses to work on some layers while ignoring others.

    I created a sprite based animation and added a 2D circle collider to it, enabled "IsTrigger" and "UsedbyEffector". Added the PointEffector2D component and set the relevant values for force and drag. In the "ColliderMask" I chose Enemies and EnemyBullets.

    But it chooses to work on only certain enemies while ignoring others, also completely ignores the bullets. This can be seen from the video I uploaded here: https://twitter.com/LewanayG/status/1172077290605465601

    As can be seen, its ignoring the bullets. and its also ignoring the turrets. The turrets and the running enemies are part of the same layer, then why is one item from a layer chosen while other is ignored?

    Thanks
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Can only think of obvious things:
    • Make sure "Use Collider Mask" is actually checked
    • Change it to "Everything" to see if it works with everything
    • Make sure the "Enemies " and "EnemyBullets" have the correct layers (on the GO with the bodies/colliders on)
    • Turn off the effector, set the collision-layer-mask and make sure you get OnTriggerEnter2D callbacks for the above layers.
    • Do a simpler test on a blank project to verify what you're doing is correct.
     
  3. farazk86

    farazk86

    Joined:
    May 31, 2017
    Posts:
    195
    Thanks for replying. All of those are already enabled and working as they should.

    What eventually did fix this was that I added RigidBody2D to the turrets and bullets. Now they all get sucked in.

    Why did this fix this? even though pointEffector settings I set the ForceTarget as Collider?

    Thanks
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    You've got bullets that move but you don't have a Rigidbody2D on them? By not adding a Rigidbody2D you're stating that you want a static collider i.e. a collider that doesn't move. This must also mean that to move them you're also modifying the Transform. This is so, so wrong. You should never ever modify the transform when using physics components, this is the primary responsibility of the Rigidbody2D itself. By not adding a Rigidbody2D the Collider2D gets added to the static ground-body. If you attempt to move it, the collider will be recreated completely at the new position. If these are more complex colliders they'll be taking a lot of time doing this as opposed to zero time when you (correctly) move the Rigidbody2D. Take a look at the profiler to see this.

    This controls the position where the force is applied i.e. the collider position. You cannot add forces to colliders, only Rigidbodies.
     
    farazk86 likes this.
  5. farazk86

    farazk86

    Joined:
    May 31, 2017
    Posts:
    195
    Youre right, I was moving bullets by updating its transform. I didint know it was considered bad practice. Thank you, I'll fix these now :)
     
  6. farazk86

    farazk86

    Joined:
    May 31, 2017
    Posts:
    195
    While changing the code for rigidBody, I remembered why I went the route of changing the transform.position in the first place. I was calculating the location of the player, and then moving the bullet accordingly, the bullet does not change position once fired, its just fired in the direction of the player.

    Code (CSharp):
    1. void Start()
    2.     {
    3.         shooter = GameObject.FindObjectOfType<Shooter>();
    4.         shooterPosition = shooter.transform.position;
    5.         direction = (shooterPosition - transform.position).normalized;
    6.         var rotation = Quaternion.Euler(0, 0, Random.Range(-maxJitter, maxJitter));
    7.         direction = (rotation * direction).normalized;
    8.     }
    9.  
    10. void Update()
    11.     {
    12.         transform.position += direction * speed * Time.deltaTime;
    13.     }
    How would I rewrite this in terms of RigidBody2D? I know that I can add velocity to the rigidBody in a certain direction with
    rigidBody.velocity = transform.right * speed;
    , but how would I give it the exact location of the player when targetting?

    Thanks
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Rigidbody2D.MovePosition. As with all physics, by default it gets updated per fixed-update which isn't per-frame. You may want to consider turning off Physics2D.AutoSimulation and manually simulating the physics with Physics2D.Simulate passing Time.deltaTime as the time-step. This reduces the determinism of the physics but in a lot of games this makes no difference. It'll certainly mean you don't need to deal with FixedUpdate anymore and your physics will always be sync'd to your visuals. You can also turn-off interpolation as it won't be required not that it would've worked anyway as you were setting the Transform directly.
     
    farazk86 likes this.