A Little Math for your Big Ideas

Vectors, Physics and Floating

Ziba Scott / @popcannibal

Let's make things...

  • float
  • and drag
  • but only underwater parts
  • and account for surface area
  • on waves
  • and have a thousand!

Rigidbodies

Gravity pulls down

Let's go the other way.

                            
                                    rigidbody.AddForce(I want it to go up)
                                    
                                

VECTORS

A vector is

Direction + Magnitude

Easily confused with a position

Tremendously useful

Vector3


Vector3 force = new Vector3(0,20,0);
rigidbody.AddForce(force);
                         
  • Float
  • Drag
  • Underwater Center
  • Surface Area
  • Waves
  • Speed

Let's make the water push back

Opposite of a vector

                
        RigidBody.AddForce(rigidbody.velocity * -1 * viscosity);
    
                    
  • Float
  • Drag
  • Underwater Center
  • Surface Area
  • Waves
  • Speed

We need to know:

  • Where are the corners of this object?
  • What corners are under water?
  • What's the center of those corners?
BoxCollider b = go.GetComponent (); Vector3 size = b.size;
BoxCollider b = go.GetComponent (); Vector3 size = b.size;

Local Space

Local Space

                
localDuckButt = new Vector3(2.3,0,0);
worldDuckButt = duck.Transform.TransformPoint(localDuckButt);
Debug.Log(worldDuckButt); // (-1,1,0)
                    
  • Float
  • Drag
  • Underwater Center
  • Surface Area
  • Waves
  • Speed

Cross products!


Vector3 v1 = Vector3.Cross(forwardVelocity, Vector3.up);

Vector3 v1 = Vector3.Cross(forwardVelocity, Vector3.up); Vector3 v2 = Vector3.Cross(forwardVelocity, v1);
                
Vector3 pointOutFront = position + (velocityDirection * 10);

for (float x = -width; x <= width; x += 1)
{
  for (float y = -width; y <= width; y += 1)
  {
    Vector3 start =  pointOutFront + (v1 * x) + (v2 * y);
    if (Physics.Raycast(start, -velocityDirection, out hit, 10))
    {
            Push it!
    }            
  }
}
                    
                    
  • Float
  • Drag
  • Underwater Center
  • Surface Area
  • Waves
  • Speed

Compare against every point! 50 times a second! Yay!

  • Float
  • Drag
  • Underwater Center
  • Surface Area
  • Waves
  • Speed
  • Compute fewer things
  • Don't trigger garbage collection
  • Threads

Deep Profiler

Compute fewer things

Break the water mesh into multiples

Compute fewer things

Vector3.magnitude has a square root

Vector3.sqrMagnitude is cheaper

Compute fewer things

raycast methods are not equal


Physics.Raycast(myRay, out hit, distance, layerMask); // 35% slower!

Physics.Raycast(start, direction, out hit, distance, layerMask)

Garbage collection

  • New has a cost!
  • Accessing mesh data always copies!
  • foreach allocates

Deep Profiler

Threading

ThreadPool makes some things super easy

                
ThreadPool.QueueUserWorkItem(myObject.MyMethod, threadNumber);
                    

but it does have a tiny allocation!

Threading

No Unity api calls

  • No Rigidbody!
  • No Raycasts!
  • No Meshfilters!
  • No Transform!
                
l2w = transform.localToWorldMatrix;

// later, in a thread

worldPosition =  l2w.MultiplyPoint(point);
                    

Conclusion

  • Vectors are direction + magnitude
  • Force and velocity are vectors
  • Transform.TransformPoint(localSpacePoint)
  • Vector3.Cross(v1, v2) == Perpendicular
  • Deep profiler

Further Reading

Water interaction model for boats in video games

- Jacques Kerner

(just google "Gamasutra buoyancy")

Ziba Scott / @popcannibal