- Home /
How to make a Light Beam levitate an object up to a spaceship.
Like what you see in the movies. I've been trying to figure out a decent way to make a cone-shaped volumetric light for a 2D game which accomplishes the following:
Press a button to turn beam on and descend from the bottom of spaceship, animating for 1-2 seconds until it hits the ground. At the same time ship is locked from moving.
Sets off a trigger on the object being levitated that causes the particle effect to start. (I have done particle script and the levitating, sort of, using a negative addforce script.) I have the trigger script but need the beam to set it off.
Measure the distance between the ship and object and levitate in a smooth transform of the y position.
As the object is levitating it disappears halfway. (I don't want to destroy it, maybe move it off to side discretely.)
I've searched thru the forums and Answers sites to find a solution...
I have tried to make the beam using Particle emitters, Cone-shaped mesh, Line renderer and a spotlight but I have problems with each one.
Particle emitters are hard to control precisely. I have an animated effect I like but I can't control the timing of the spawning. Also, can one particle trigger off another particle emitter?
The mesh I don't have much experience with so admittedly I probably haven't done all I could but it doesn't seem suited for what I need especially the animating part.
Line renderers can't animate growing in the y-scale so doesn't meet my needs.
Spotlight - I am using 100% ambient light so any light is not going to be seen in my game view. Also, I couldn't figure out how to make it trigger particles upon turning on.
Can someone point me in the right direction and help me accomplish the above. I'm trying to create my first game using Unity. Ssorry for the length of my post.
I'd be really grateful for some help.
Answer by JustinLloyd.du · Aug 04, 2010 at 10:21 PM
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.
Justin,
Yes! What you're describing is EXACTLY what I am trying to achieve. As I replied to Wolfram above, I created a mesh cone ins$$anonymous$$d with a mess collider with a trigger. This should set-off my particle animation on the object I am trying to tractor beam.
I will UV it later but my main focus is to get the tractor beam animation with the object shrinking in scale. How did you achieve this? Can you share a bit of your expertise to put me on the right path? I'd really be grateful as this is my first Unity game I'm trying to complete. Thanks
Thanks again Justin, your answer was very thorough and helpful, I'm sure it'll help many others in the community as well.
Your outline I hope is all I need, but if your offer of a tutorial comes thru I'm sure it'll save me from pulling out much of my hair in the process. :-)
Cheers,
Answer by Wolfram · Aug 04, 2010 at 05:15 PM
The mesh approach is probably still the best. Model a cone with the tip at the origin, and the other at (0,0,1), with a certain radius.
- You can orient that cone wherever you like with transform.LookAt, you can scale its length with transform.localScale.z, and diameter with transform.localScale.x and .y.
- In the mesh import settings you can enable "create mesh colliders", so your cone will come with a collider you can use to trigger stuff.
- If you also apply uv mapping while modellilng your cone, you can even create an animated texture for that cone (for example, an alpha texture only showing rings with the rest being transparent).
Thanks for the reply. I've created the $$anonymous$$esh cone with a $$anonymous$$esh 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?
The easiest way would be to use iTween or Ani$$anonymous$$ate: 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}); }