How can I reattach the player transform after using DetachChildren() to flip the parent?

I want my player to "ride’ the moving object (which has a definite front and back) so I’m making him a child of the object with OnCollisionEnter2D. Before flipping the object, I am using DetachChildren() but need to attach him again once the object is flipped (since OnCollisionExit2D will not be called until the player leaves the object). Any suggestions would be greatly appreciated!

@Danao

I tried to replicate your setting and came to the following suggestions: When the player is a child of the moving object it should be recentered (a position of (0,0,0)) so that it’s previous position doesn’t get affected by the flip (wich is probably what causes the erratical movement).

Other Solutions would be to set the moving object a child of the player, then the player follows the moving object but with an undampened offset. A better approach would be to unparent the moving object from the player (have them both separate) and add the SmoothFollow script from the Standard Assets to the player, wich you can enable when OnCollisionEnter and disable when OnCollisionExit.

Another problem could be that you use OnCollision instead of OnTrigger and set the Collider of either the player, the moving object or both to “is Trigger”, so that they don’t collide constantly, wich could also be the source of your problem.
The SmoothFollow.cs script:

using UnityEngine;

namespace UnityStandardAssets.Utility
{
	public class SmoothFollow : MonoBehaviour
	{

		// The target we are following
		[SerializeField]
		private Transform target;
		// The distance in the x-z plane to the target
		[SerializeField]
		private float distance = 0f;
		// the height we want the camera to be above the target
		[SerializeField]
		private float height = 0.5f;

		[SerializeField]
		private float rotationDamping;
		[SerializeField]
		private float heightDamping;

		// Use this for initialization
		void Start() { }

		// Update is called once per frame
		void LateUpdate()
		{
			// Early out if we don't have a target
			if (!target)
				return;

			// Calculate the current rotation angles
			var wantedRotationAngle = target.eulerAngles.y;
			var wantedHeight = target.position.y + height;

			var currentRotationAngle = transform.eulerAngles.y;
			var currentHeight = transform.position.y;

			// Damp the rotation around the y-axis
			currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);

			// Damp the height
			currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);

			// Convert the angle into a rotation
			var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);

			// Set the position of the camera on the x-z plane to:
			// distance meters behind the target
			transform.position = target.position;
			transform.position -= currentRotation * Vector3.forward * distance;

			// Set the height of the camera
			transform.position = new Vector3(transform.position.x ,currentHeight , transform.position.z);

			// Always look at the target
			transform.LookAt(target);
		}
	}
}

The solution was much more simple and elegant than I was originally trying to make it. All I needed to do was add a bool to check if “colliding” was true during the change of direction, if so, then use SetParent to reattach the player:

using UnityEngine;

    public class:  MovingObject : MonoBehaviour {
    
        public float speed;
        public float distance;
        private float xStartPosition;
        private Transform PlayerAttach;
        private bool colliding = false;
    
        void Start()
        {
            xStartPosition = transform.position.x;
        }
    
        void FixedUpdate()
        {
                if ((speed < 0 && transform.position.x < xStartPosition) || (speed > 0 && transform.position.x > xStartPosition + distance))
                {
                transform.DetachChildren();               
                speed *= -1;
                    // Multiply the object's x local scale by -1
                    Vector3 theScale = transform.localScale;
                    theScale.x *= -1;
                    transform.localScale = theScale;                    
                }
                transform.position = new Vector3(transform.position.x + speed * Time.deltaTime, transform.position.y, transform.position.z);

if(colliding = true)
{
PlayerAttach.SetParent(gameobject.transform);            
}
         
    void OnCollisionEnter2D(Collision2D other)
{
        other.transform.SetParent(gameObject.transform);
        PlayerAttach = other.transform;
        colliding = true;
}

private void OnCollisionExit2D(Collision2D other)
{
           colliding = false;
            transform.DetachChildren();           
}
}