August 11, 2022, 05:00:51 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


I need help with code.

Started by J B Wood (Zumwalt), July 13, 2007, 06:28:38 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

J B Wood (Zumwalt)

Here is what I need, I need code that given a start point and an end point in 3d space (X,Y,Z), can by utilizing RayCasting detect a plane beneath that point, return the distance, divide that up by a user inputted amount (say 12 segments), then from the start, randomly place the next point beneath the starting point at a random angle between 0 and 90 (user defined), and repeat until the  las point touches the ray intersected point.

Now to add chaos to this, I need each point along the way once reched to have branches randomly created only when that point is reached from 0 to user defined amount with a max length of current positin to destination -1. So meaning that if the point was the second one on the list, the branches if choosen by the user is max 3, and rolled a 2, 2 new branches off the trunk are made that go out the same distance as exists between each trunk link. Now each branch can also split at that length point by the reduced amount of available pieces to it.

This would repeat until those branches reach the end of there span. Each branch link would extend out in an angle of 15 degrees to 45 degrees.

What I am having trouble making is lightening simulator.
One thing I am bad at is math.

So when you see lightening strike from the clouds to the ground, that is what I am attempting to do.
I am pretty positive that this can be easily done with a few formulas and very little code since the return element of the function would be an array of all points along the tree, or rather an arraylist with children arrays where each piece of the trunk split. I have only drawn this out on paper so far as to what I want done and when lightening is triggered from a random x,y,z location for source, each bolt should in theory end up looking completely different.

If anyone has ever done this before or is willing ot help, please let me know! :) many thanks

J B Wood (Zumwalt)

Ok, I got this working in C# for Unity which was my target for the code anyway. If someone wants to take this code and convert it to either EBasic or Aurora, go for it. I am sure it will work here just as well. I don't have the time to convert it or I would. Its really straight forward.
You don't have to worry about the two using parts at the top or the class definition of MonoBehaviour, but the rest of the code should be useful if anyone is looking to make there own random lightening bolts.

Ultimately, you give it a start postition of a Vector3 and and end position of a Vector3, then replace the Gizmos.DrawLine with the object you want to have between the two points, a line, a mesh, what ever. The Gizmos is nothing more than a test object used to test in scene what is going on, nothing the player sees. Hope someone finds this code useful, took me a few days to invent in my spare time.

If I get time, I'll convert it to classes for both Aurora and EBasic, but might not be for a while, I am swamped.
I have also attached an image of the end result of one of the random bolts.

HTH Have Fun.


using UnityEngine;
using System.Collections;

public class Bolt : MonoBehaviour {
public float scale;
public float strikeDiameter;
public Vector3 start,end,stepNext,stepLast,rndPoint;
public GameObject eTarget;
float lastPointY,distBetween;

void Start () {
scale=20.0f;
strikeDiameter=5.0f;
}
void Update () {}

void drawBolt()
{
Gizmos.color=Color.yellow;
start = this.transform.position;
end = eTarget.transform.position;
distBetween=(start.y-end.y)/scale;
lastPointY=start.y-distBetween;
stepLast=start;
stepNext.x=(start.x/strikeDiameter);
stepNext.z=(start.z/strikeDiameter);
int tmpScale;
for(int i=0;i<scale;i++)
{
rndPoint.x=Random.Range(-strikeDiameter,strikeDiameter);
rndPoint.z=Random.Range(-strikeDiameter,strikeDiameter);
end.x=(stepLast.x+stepNext.x)+rndPoint.x;
end.y=lastPointY;
end.z=(stepLast.z+stepNext.z)+rndPoint.z;
Gizmos.DrawLine(stepLast,end);
if(i>0 && i<scale-1)
{
tmpScale=(int)(scale-i)/2;
drawBranches(Random.Range(1,10),Random.Range(tmpScale,(int)scale),stepLast);
}
stepLast=end;
lastPointY=lastPointY-distBetween;
}
}

void drawBranches(int shouldDraw,int howDeep,Vector3 connectPoint)
{
Vector3 iEnd,iStepNext,iStepLast,iRndPoint;
iStepLast=connectPoint;
iStepNext.x=(iStepLast.x/strikeDiameter);
iStepNext.y=(iStepLast.y/strikeDiameter);
iStepNext.z=(iStepLast.z/strikeDiameter);
float iLastPointY=lastPointY;

if(shouldDraw >8)
{
for(int i=0;i<howDeep;i++)
{
iRndPoint.x=Random.Range(-strikeDiameter,strikeDiameter);
iRndPoint.y=Random.Range(-strikeDiameter,strikeDiameter);
iRndPoint.z=Random.Range(-strikeDiameter,strikeDiameter);
iEnd=iRndPoint+iStepLast;
Gizmos.DrawLine(iStepLast,iEnd);
if(i>0 && i<howDeep-1)
{
drawBranches(Random.Range(1,10),2,iStepLast);
}
iStepLast=iEnd;
iLastPointY=iLastPointY-distBetween/2;
}
}
}

public Transform target;
void OnDrawGizmosSelected()
{
if(target != null)
{
drawBolt();
}
}
}