Had to do this very effect in a game a few years ago. My solution was a billboarded quad with a simple texture on it, and I modulated the RGB and alpha to make it glow. I think it also had a glow shader of some description attached to it, but I could be remembering it wrong. It might have just been the texture with transparency at the edges.
The object being tractor beamed up was translated upwards in the Y towards the source of the tractor beam, and also in the X & Z to make sure it became centered, just in case it wasn't to begin with.
I also animated the scale of the object caught in the tractor beam so that it appeared to shrink as it went up in to the spaceship.
You could use a cone mesh, but that would just be wasting polygons unless you want to be able to view the tractor beam cone from odd camera angles or if you had a specific effect you were trying to animate.
To test for collisions, I just tested distance from the origin at the base of the cone with a simple range test. You could do the same with a sphere collider too.
Further Notes:
For the tractor beam object, create your cone mesh (or billboarded quad). It's origin should be at the point of the cone, i.e. the top.
You can use a sphere collider parented to the cone and positioned at the base of the cone, or perform a simple distance check based on the radius of the cone base, no collider required though this may not be the best practice in the Unity engine.
I recall making the collision area smaller than the base of the radius of the tractor beam when the computer was using it against the player, giving the player just enough warning to dodge out of the way. When the player had control of the tractor beam, the collider area was slightly larger than the base of the radius of the cone so that the player did not have to be precise in their targeting against enemies. Basically, be kind to your player.
For the scaling of the object, calculate the vertical distance between the object's origin or the object's centroid if the origin is some weird location, or alternatively put a marker in your 3D file so that the center of the object is precalculated, and the tip of the cone, i.e. the origin of the tractor beam. Normalise the distance so that at the furthest point away where the tractor beam is still effective the distance is 1.0 and at the tip of the cone it is 0.50 or some such arbitrary value. This means your object won't completely shrink to zero as it levitates up. As the distance between the center of the levitating object and the tractor beam origin decreases, you multiply the scale transform of the object by the normalised distance. This makes the object be normal sized as it steps in to the beam, and about 70% of the size just before it fades out, or whatever other cut off value you deem looks good.
You will want to fade out your levitating object too, so that it disappears over time. You do the fading with a normalised distance again, but this time make it between 1.0 and 0.0 as the possible range of values. I am not certain how to perform a fade of an entire object in Unity at this point. I am sure there is a way to do it, and probably quite simply too.
To get the distance between the centroid of the object (or it's origin if the origin is close to the center) and the tractor beam origin you simply subtract the world Y value of each object, and then scale that result by the total possible distance of the tractor beam,
e.g. normalised_distance = 1.0 / MAX_DISTANCE * Math.abs(object.transform.Y - tractor_beam.transform.Y);
For the X & Z translation, just translate your object over time in the X & Z until it enters the tractor beam sweet spot. The radius of the base of the cone, or thereabouts, is the area that the tractor beam has an effect on objects, and then there is a second inner radius which is the sweet spot. When the object hits the sweet spot, your code can stop worrying about getting it centered, it's good enough. Think of the base of the cone radius and the sweet spot as a doughnut with a hole. The hole is the sweet spot.
To translate in the Y, you can LERP from the position the object was at to the tractor beam origin, or you can just translate the Y of the object until it gets close enough.
If your tractor beam can work on lots of differently shaped objects, e.g. small square boxes and very long boxes, don't worry about having part of the object sticking out of the tractor beam. So long as it is centered-ish, it'll look good. If you're that worried about really big objects sticking part way out, add a little wobble to the object as it gets sucked up, make it look like its too big for the tractor beam to lift.
I will see what I can achieve in Unity this weekend and maybe post it as a tutorial on my website when I am done. I cannot promise anything, it depends on how my week and weekend goes. It will be interesting to try it in Unity.
Thanks for the reply. I've created the Mesh cone with a Mesh Collider with 'is Trigger' on and made it the child of my Ship Game object. I will work on the UV mapping to get the right effect for the beam. But I need to be able to turn it on and off in a way that shows the beam descend from the ship and go back into the ship by pressing a button. Could you share some basic code on how to do that?
– anon24724772The easiest way would be to use iTween or AniMate: var length:float; var radius:float; var duration:float; function Show(){ iTween.scaleTo(gameObject,{"time":duration, "x":radius, "y":radius, "z":length}); } function Hide(){ iTween.scaleTo(gameObject,{"time":duration, "scale":Vector3.zero}); }
– Wolfram