How would I go about generating a line from any point on the edge of the screen that will always aim for the centre of the screen, that will randomly change angle within a certain radius (without doubling back on itself), and once it has reached the centre, to fade out along the path?
This probably sounds like nonsense, so I created a .gif to show what I mean:
As other’s have mentioned, this is a wide question with potentially multiple technical issues. I decided to give it a try mostly because I wanted to see what it would look like. Typically on UA we look for questions with a narrower focus.
This code works by Instantiating a game object with a script and a TrailRenderer.
Create an empty game object
Attach the following script
Attach a TrailRenderer component
Adjust the TrailRenderer
Make this game object a prefab
Delete the game object from the scene
I setup my TrailRenderer with:
Time: 0.5
Start Width: 0.02
End Width: 0.02
This code expects the target to be a game object with the name “Target”. Modify as necessary.
#pragma strict
var target : Transform;
var legDist : float = 0.3; // Distance for each leg
var period : float = 0.05; // Time between each leg
var maxOffset : float = 0.5; // Maximum distance to scale angle
var startNarrowDist : float = 2.0; // The distance the offset starts to narrow
var maxLive : float = 1.0; // Maximum life after hit
private var hasHit = false;
private var timestamp : float = Mathf.Infinity;
private var _transform : Transform;
function Start () {
_transform = transform;
target = GameObject.Find("Target").transform;
Fire();
}
function Fire() {
var toTarget = target.position - _transform.position;
var lastPos = _transform.position;
var perp = Vector3.Cross(Vector3.forward, toTarget).normalized;
transform.position += transform.forward * -0.001;
yield;
while (true) {
var dist = Vector3.Distance(target.position, _transform.position);
var angle : float;
if (_transform.position == target.position) {
if (!hasHit) {
hasHit = true;
timestamp = Time.time + maxLive;
}
else {
if (Time.time >= timestamp) {
Destroy(gameObject);
}
}
}
else if (dist <= legDist) {
_transform.position = target.position;
}
else {
lastPos += toTarget.normalized * legDist;
var perpDist = maxOffset;
if (dist < startNarrowDist) {
perpDist = maxOffset * dist / startNarrowDist;
}
_transform.position = lastPos + perp * Random.Range(-perpDist, perpDist);
}
yield WaitForSeconds(period);
}
}
You fire it by Instantiating the prefab at some position. It destroys itself when it is finished. Note this a 2D solution. For 3D there are likely some changes to be made. One change would be this line:
var perp = Vector3.Cross(Vector3.forward, toTarget).normalized;
…would become:
var perp = Vector3.Cross(Vector3.up, toTarget).normalized;
One possible approach would be to have a line renderer start at a random point on the edge of the screen and end at the center. To get a random (world coordinate) position outside the screen, off the top of my head, I’d say add a random value between [-1,1] to the x & y location of the camera. The center of the screen is camera.transform.forward+1f
Then, divide the line to how many segments you want and add some variation to each mid-point. You’ll probly have to play with the values a little to get consistent good results.
For the fading effect you could animate a transparent material (possibly a gradient of some sort) across the line to give the impression of a beam advancing and then fading.
There is also a procedural lightning generator( + other procedural examples ) available on the asset store, which may or may not be suitable for your needs.