I'm in the early stages of a new game, and need help developing the movement.
The problem boils down to this: Imagine a donut shaped tunnel (i.e. a cyclotron/torus), with objects that move('float') within the lumen of tunnel. I'd like those objects to continuously circle around the tunnel. I can simuluate the motion using splining, but there will be many objects flying around, and I like them to float through the tunnel more randomly/realistically, using either physics or direct manipulation of the transforms.
I've tried just using physics, and applying a forward force, but eventually the object just ends up sliding along the outer wall of the tunnel (see this link http://www.orgoquest.com/unitytest/temp.html ).
My latest idea was to have the object move forward along it's z-axis, do a raycast to the right from the object to the outer wall, get the normal of that hit point, and rotate the object so that it's z axis is directed 90 degrees to the normal, and then move forward along the z-axis. In my mind, this would cause the object to move around the curve at a constant distance from the outer wall, but it's not working. Maybe because I'm doing something wrong with the vector math.
I was hoping someone could point me in the right direction to try to accomplish this, either using the idea above, or anything else out there.
Edit: Although I'm using a torus now, in the future the shape will be a tunnel of arbitrary direction, not necessarily in a circle. The way the cells move in this video http://www.youtube.com/watch?v=tKgroDE4DHo&feature=player_embedded at the 46-49 second mark is what I'm trying to recreate.
Moving inside a torus
I never took Bio, so while I correctly assumed the meaning of lumen in this context, I had to look it up to be sure.
Because the shape is constant, we can make some assumptions and do some simple calculations to make this work because we're just moving in a circle.
The simple solution is to center the pivot of motion at the center of the torus with the object positioned inside the tunnel and then just rotate. This can be done with some simple parenting and rotating the parent, changing the pivot itself or just getting the center of the torus which is quite easy especially if the parent is the torus.
To fly in a circle with forces is a pain. You must constantly apply a relative force in the direction that you are turning, so you have to keep track of this direction. Something like turning the object with torque, using drag, no gravity and no angular drag:
The problem is that you can't really control the circle terribly well and if you get moved off your center, it becomes trying to get it back under control.
As an alternative, you could also apply a sort of "gravity" towards the center of the torus as well, to keep the object's rotation under control, but this becomes a bit harder to maintain as a circle.
Using a kinematic rigidBody, you could just do something like the orbit camera script where you rotate the object and translate along an axis.
In the natural world, there is nothing truly random, but the motion in a system that we would perceive as "random" is a product of a reasonably undetermined start motion/position + well tuned forces and adjustments. Between the complexities of force occlusion, surface interaction and pressure systems for multiple objects in even a stable medium, it's rather challenging to calculate the reality of how objects would react, so in general randomness as well as physics systems provide approximations.
Believable randomness can be a pain to create. One of the best solutions I've seen was to sample random noise (see this Unite presentation). There are too many ways to do randomness to mention, but the important part is not to directly assign random values to positions unless you know that they will smoothly interpolate. I also recommend taking a look at some of the flocking scripts as they provide some useful information on following a direction, but doing so less strictly.
Assuming you're rotated into position (which you can control by a random speed too if you wanted), you only have two axes left to worry about for random motion along the axes extending from the center and to the object and the axis you rotated around. If you orient the object relative to its orientation around the torus, it's actually a lot simpler as the two axes are actually two axes of the object's transform.
You could generate a random point along the plane formed by these axes and move towards it (or even specifically within the circle defined by the interior of your torus). You could create a speed vector of adjustment and adjust it's values by small random amounts, moving at this random vector speed, changing the speed's direction away from the walls as you get further from the calculated position so that you never hit the walls. Move randomly as your use case best dictates.
With physics forces
If you're not too concerned by the motion in the circle being a bit inaccurate, you could consider calculating the position where it should be as was done in the non-force driven methods and applying a force in that direction. You can then add random motion by either offsetting the point relative to the parent or applying a force along the plane formed by the object and the center of the torus at set intervals. You don't want to apply the random changes all the time because they can really mess up your simulation unless they are quite small.
Because this doesn't set the position explicitly, even with fairly strong random forces and collisions, as long as the object doesn't get stuck, it should continue along the initial circuit. If it does get stuck, the next time the calculations bring the destination back around, it is possible that it will re-align itself.
Moving inside arbitrary shapes
This is a bit more problematic because we can't assume much.
The general solution to this problem is to find the "forward" direction at that point in the tunnel and keep it moving that way, regardless of what else happens, assuming that your intent is to have it continue along that tunnel (like being in a stream of water, applying "constant" force from "behind"). The first problem with arbitrary shapes is how you decide what forward is and finding this can be much less obvious.
Programmatically, you could find the center/direction by performing raycasts, but with truly arbitrary shapes, assuming you aren't aligning yourself to a wall or something, you don't necessarily know which way to raycast at any given point and even if you do, it still leaves you with at least two directions (positive and negative) to use for the forward direction and very little way to really be sure which is correct.
The approach I would take is to set a center point probably with a series of waypoints and I might even set them up as bezier curves to get something smoother and I would most importantly know which way is forward by the order of the points. Using waypoints, you will of course need to know where you are along the path, which can be generally determined to some extent by your distance from the current (and subsequent/preceding if applicable) waypoints. Knowing my center point and direction, I would move my object with the path. Note that by stretching, skewing waypoint distances, you can also indicate speed adjustments based on flow, etc. Your waypoints could even be what you use to define your shape in the first place if you are generating your shape from a series of points and then your points could contain additional information about size of the shape at that point, etc.
To achieve random motion, I could do something like the above adjustments by random speeds or offsets, or set up alternate waypoints at certain points and have the object randomly interpolate between the two equations as appropriate and that would look sort of more natural while still being tunable.
As an alternative to waypoints, you could set up a series of trigger volumes that would apply force in the direction of the tunnel at that point, but this could lead to a lot of these for more complex tunnels and may get to be too much overhead depending on your use case. Also, remember to disable/enable and/or create/destroy stuff based on some LOD.
The point is that you know what forward is at any given point and push in that direction, while not immediately losing the initial motion prior to the forward motion being applied.
Sliding along the wall
If you're using physics, have you considered tuning your physic materials? Try adding things like bounciness and lowering the friction as this may be more like what you actually meant by random motion and at the very least should address your sticking to the wall some, as long as you aren't constantly pushing towards the walls.. If you do it this way, in a system without (or with very little) drag, you could apply a random force at the start and then apply forces along the tunnel's curves and narrows/expanses to adjust the direction/speed as appropriate, you can just let the physics engine drive it for you with bounces, etc.
If this doesn't resolve that issue or if you're not using physics, you could maintain a variable that stores your movement vector (or even use rigidbody velocity if you need) and, on collision calculate a reflected vector away from the surface and ensure that it moves in this vector.
Here is how we solved a very similar problem - we have an object hovering in a tunnel, where we control the distance between the object and the tunnel wall under the object (under here is relative to the vehicle's orientation - if the object is upside down, then the distance is between the object and the tunnel wall at the top).
There are three components:
The first is the easiest - just apply a force in the direction of the forward vector of the object (I assume that your object won't be spinning as it moves).
The second is also fairly easy. We use a spring/damper system to do this:
(Note, you might just want to check the signs). You can find some more notes on this technique here.
The third system is a bit trickier to implement. Basically, you have to correct the pitch and roll of the object, relative to the tunnel wall under the object. This can be done as explained here. This explanation assumes that the ground is purely horizontal. To make it work for a tunnel wall, you have to convert it to the coordinates normal / tangent to the tunnel wall. This is the tricky part. We did it this way (it is somewhat clumsy, perhaps there is a better way).
Now you can use the roll and pitch of this transform to calculate a corrective torque as explained in that answer. Although you could use damping, we did not.
Well, this is somewhat tricky to explain, I hope I at least gave you a good starting point.