Lots of ways to do this, depends how you've created your water waves. Assuming it's a mesh that's being manipulated through script, take an invisible "surface object" (a plane or box with collider and rigid body) and attach your floating object to it with a spring joint. That way your floating object reacts in a very realistic manner: you can simulate heavier objects with looser springs, etc. The other way is to do it with script, and I think Yoggy's boat demo a while back did this.
Another solution is to use the physics system to add buoyancy forces when the object enters a trigger. I'm using this method with a "buoyant object" script. Any rigidbody entering a trigger tagged with "fluid" has buoyant forces added based on the objects volume. This code is based on an example that was posted on the forums quite a while ago, though I've changed quite a bit after many revisions. Code (csharp): // density here is killograms per cubic meter. Unity's world units are meters and mass is commonly assumed to be killograms // Density of wood: 600 kg / cu.m // Density of water 1000 kg / cu meter // Density of iron 7000 kg / cu meter // densityOfBody = b.mass / curBodiesVolume[i]; var divider = 1.0; var airborneDrag = -1.0; //If left at -1 will use the Rigidbody Drag var fluidDrag = 0.0; private var fluidDensity = 1000.0; private var displacement = 0.0; private var myRenderer : Renderer; private var myRB : Rigidbody; private var myColliders : Array; private var timer = 0.0; function Start(){ var renderers = transform.root.gameObject.GetComponentsInChildren(Renderer); var rendMax = Vector3(0,0,0); for (var ren : Renderer in renderers){ if(ren.bounds.size.sqrMagnitude>rendMax.sqrMagnitude){ rendMax = ren.bounds.size; myRenderer=ren; } } if(myRB==null) myRB = GetComponent(Rigidbody); if(myColliders==null) myColliders = GetComponentsInChildren(Collider); for(var col : Collider in myColliders){ displacement += col.bounds.size.x*col.bounds.size.y*col.bounds.size.z; } displacement = displacement/divider; if(airborneDrag<0)airborneDrag = myRB.drag; } function OnTriggerEnter(c : Collider){ if(c.tag=="fluid") myRB.drag=fluidDrag; } function OnTriggerStay(c : Collider){ if(myRenderer==null)return; var timetemp = Time.realtimeSinceStartup; if(c.tag=="fluid"){ var surfaceYPos = c.transform.position.y; var bottom : Vector3 = transform.position; for(var col : Collider in myColliders){ if(col==null) continue; var temp = col.ClosestPointOnBounds(transform.position-Vector3(0,100,0)); if(temp.y<bottom.y) bottom = temp; } var bottomToSurface : float = (surfaceYPos-bottom.y); var bottomToCenter : float = (bottom - myRenderer.bounds.center).magnitude; var pctSubmerged : float = Mathf.Clamp01(bottomToSurface/(bottomToCenter*2)); var force : Vector3 = displacement*fluidDensity*pctSubmerged*-1*Physics.gravity; bottom = Vector3.Lerp(bottom,transform.position,0.75); myRB.AddForceAtPosition(force,bottom); } timer += Time.realtimeSinceStartup-timetemp; } function OnTriggerExit(c : Collider){ if(c.tag=="fluid") myRB.drag=airborneDrag; }