Collision with object causing issues with player rigidbody2d

Hello,

I am having a weird issue and I am hoping someone can tell me what is wrong! I have a top down game and a character I am trying to get them across a river, whilst spawned objects fall vertically from the top of the scene. I wanted to simulated a river current to add a bit of extra complexity, so I created an empty gameobject with a box collider and the following script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Water_Current : MonoBehaviour
{
    public enum Direction { Down, Up, Left, Right }
    public Direction flowDirection;
    [SerializeField] private float _flowSpeed;

    private void OnTriggerStay2D(Collider2D other) {
        if (other.tag == "Player") {
            if (flowDirection == Direction.Down) {
                other.transform.Translate(Vector3.down * _flowSpeed * Time.deltaTime);
            } else if (flowDirection == Direction.Up) {
                other.transform.Translate(Vector3.up * _flowSpeed * Time.deltaTime);
            } else if (flowDirection == Direction.Left) {
                other.transform.Translate(Vector3.left * _flowSpeed * Time.deltaTime);
            } else if (flowDirection == Direction.Right) {
                other.transform.Translate(Vector3.right * _flowSpeed * Time.deltaTime);
            }
        }
    }
}

I have a script for spawning the objects that will flow down the river:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class River_Object_Spawner : MonoBehaviour
{
    private Level_Config _levelConfig;
    [SerializeField] private GameObject[] _objects;
    [SerializeField] private float _xLeft, _xRight, _yTop, _yBottom;
    [SerializeField] private float _objectSpawnTimeStartRange, _objectSpawnTimeEndRange;
    public float objectSpeedStartRange, objectSpeedEndRange;
    public float objectOutOfRange;

    private void Awake() {
        _levelConfig = GameObject.Find("Level_Config").GetComponent<Level_Config>();
    }

    public void StartSpawnRoutines() {
        StartCoroutine(ObjectSpawnRoutine());
    }

    public void StopSpawnRoutines() {
        StopCoroutine(ObjectSpawnRoutine());
    }

    public IEnumerator ObjectSpawnRoutine() {
        while (true) {
            float randomSpawnTime = Random.Range(_objectSpawnTimeStartRange, _objectSpawnTimeEndRange);
            int randomObject = Random.Range(0, _objects.Length);
            Instantiate(_objects[randomObject], new Vector3(Random.Range(_xLeft, _xRight), Random.Range(_yTop, _yBottom), 0), Quaternion.identity);
            yield return new WaitForSeconds(randomSpawnTime);
        }
    }
}

Each object has the following script attached to it:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class River_Object : MonoBehaviour
{
    private River_Object_Spawner _spawnManager;
    [SerializeField] private float _objectSpeed;

    private void Awake() {
        _spawnManager = GameObject.Find("Spawn_Manager").GetComponent<River_Object_Spawner>();
    }

    private void Start() {
        _objectSpeed = Random.Range(_spawnManager.objectSpeedStartRange, _spawnManager.objectSpeedEndRange);
    }

    private void Update() {
        if (transform.position.y < _spawnManager.objectOutOfRange) {
            Destroy(this.gameObject);
        }
    }

    private void FixedUpdate() {
        this.gameObject.GetComponent<Rigidbody2D>().AddRelativeForce(Vector2.down * _objectSpeed * Time.deltaTime);
    }
}

Every works fine up to a point. The player can move and enter the water current collider. The water current starts to push the player down and the player can fight against this. The objects are spawned correctly and fall as expected.

The issue is when one of the objects collides with the player. The player is forced down to the bottom of the screen, outside of the water current box collider and stops. The player can move around, but is unable to reenter the collider. Dragging the player into the collider does not work as the player just shoots straight down and out of the bottom of the collider again.

I am really not sure why this happens and I am scratching my head. If anyone has any ideas, I would really love to hear them :slight_smile:

Many Thanks,

J

Have you tried to not use the transform in the “Water_Current” script but the rigidbody of the player for the movement (but not add a velocity here only set a constant velocity)? The reason is perhaps using the transform of the player is in conflict with the rigidbody component of the player.

Hi,

Thank you for your response. I figured it must be something with the water_current script since the player can move outside of the collider fine after being hit. I also wondered if there was some issue with the transform.Translate, so I
changed the script to:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Water_Current : MonoBehaviour
{
    public enum Direction { Down, Up, Left, Right }
    public Direction flowDirection;
    [SerializeField] private float _flowSpeed;

    private void OnTriggerStay2D(Collider2D other) {
        if (other.tag == "Player") {
            if (flowDirection == Direction.Down) {
                other.GetComponent<Rigidbody2D>().AddForce(-transform.up * _flowSpeed, ForceMode2D.Force);
            } else if (flowDirection == Direction.Up) {
                other.GetComponent<Rigidbody2D>().AddForce(transform.up * _flowSpeed, ForceMode2D.Force);
            } else if (flowDirection == Direction.Left) {
                other.GetComponent<Rigidbody2D>().AddForce(-transform.right * _flowSpeed, ForceMode2D.Force);
            } else if (flowDirection == Direction.Right) {
                other.GetComponent<Rigidbody2D>().AddForce(transform.right * _flowSpeed, ForceMode2D.Force);
            }
        }
    }
}

This works perfectly, although I am really not sure what the conflict is with the original. I am just happy it works though :smile:

Many Thanks,

J