Hello community,
I’m quite new to Unity3D and having some problems with my latest piece of script.
But first of all some explanation!
I’m using it to simulate the ballistics of any fast moving projctile in 3D space that can’t be realized by using Rigidbodies. In fact it does something very simmilar to the normal raycasting one would use for shooting. But in way of real world’s ballistics being slightly more complex, especially for great distances, it does not only create one straight raycast, but many of them based on the formula of an angular throw. As this procedure as a bit complicated to describe (and even to understand :lol: ), pardon my idleness of giving further details! ![]()
The only thing important to know is, that I want my script to simulate the trajectory of my bullets physically correct and in this way let them take some time to reach a target.
The problem is that a Raycast Hit is returned immediately as if the bullet would fly with speed of light. To solve this I let my script calculate the time a projectile with a certain velocity would need to cover the distance to the target and then do a “yield WaitForSeconds()” before actually casting the ray.
Well everything seemed to work perfect: The time is calculated correctly, the the raycast is done and there is a delay between “pulling the trigger” and RaycastHit.
But for any reason this delay is far to big :!: :?: :x
For example a bullet with a velocity of 1000 units per second would take about 3 seconds to cover a distance of 100 meters! Eigther my maths is even worse than I’ve thought or there is something wrong with the “yield” class :lol: ![]()
Can anyone out there help me please!?
Thanks in advance for any productive kind of help!
Now here is the whole code. Hope it won’t slay you:
var start : Transform;
var inaccuracy : float = 0.1;
var smokeMaterial : Material;
var startColor : Color = Color (1.0, 1.0, 1.0, 1.0);
var endColor : Color = Color (1.0, 1.0, 1.0, 0.0);
var projectileVelocity : float = 10.0;
var bulletHole : Transform;
var exitHole : Transform;
var fireDelay : float;
var shotSound : AudioClip;
var solvingInterval : float = 1.0;
var solvingCount : int = 100;
var leaveTracer : boolean = true;
var damage : float =1.0;
private var nextFire = 0.0;
private var player : Transform;
private var muzzleFlash;
function Awake()
{
player = GameObject.Find("First Person Controller").GetComponent(Transform);
muzzleFlash = GameObject.Find("First Person Controller/Main Camera/ACOG/lauf/MuzzleFlash").particleEmitter;
}
function Update ()
{
if (Input.GetButton("Fire1"))
{
if (Time.time > nextFire)
{
nextFire = Time.time + fireDelay;
Shoot();
}
}
}
function Shoot()
{
audio.PlayOneShot(shotSound);
muzzleFlash.Emit (1);
var startPoint : Vector3 = start.transform.position;
var lastPoint : Vector3 = startPoint;
var yAngle : float = player.transform.rotation.eulerAngles.y;
var offsetX : float = solvingInterval * Mathf.Sin(yAngle * Mathf.Deg2Rad);
var offsetZ : float = solvingInterval * Mathf.Cos(yAngle * Mathf.Deg2Rad);
if (transform.rotation.eulerAngles.x >= 180)
{
var xAngle = (360 - transform.rotation.eulerAngles.x);
}
else
{
xAngle = -(transform.rotation.eulerAngles.x);
}
if (leaveTracer == true)
{
line = new GameObject ("SmokeEffect");
fadeout = line.AddComponent("AlphaFadeout");
fadeout.fadeSpeed = 0.1;
visual = line.AddComponent("LineRenderer");
visual.useWorldSpace = true;
visual.SetWidth (0.01, 0.2);
visual.material = smokeMaterial;
visual.SetColors (startColor, endColor);
visual.material.SetTextureScale ("_MainTex", Vector2(10, 1));
}
var missX : float = Random.Range(-inaccuracy, inaccuracy);
var missY : float = Random.Range(-inaccuracy, inaccuracy);
var missZ : float = Random.Range(-inaccuracy, inaccuracy);
for (i=0; i<solvingCount; i++)
{
var timeToTarget : float = ((i * solvingInterval/(projectileVelocity * (Mathf.Cos(xAngle * Mathf.Deg2Rad)))) - ((i - 1) * solvingInterval/(projectileVelocity * (Mathf.Cos(xAngle * Mathf.Deg2Rad)))));
yield WaitForSeconds(timeToTarget);
var offsetY : float = (-(-Physics.gravity.y/2) * (Mathf.Pow (i * solvingInterval, 2)/(Mathf.Pow (projectileVelocity, 2) * Mathf.Pow (Mathf.Cos (xAngle * Mathf.Deg2Rad), 2))) + i * solvingInterval * Mathf.Tan (xAngle * Mathf.Deg2Rad)) + i * missY;
var nextPoint : Vector3 = Vector3(startPoint.x + i * (offsetX + missX), startPoint.y + offsetY + i * missY, startPoint.z + i * (offsetZ + missZ));
var dis : float = Vector3.Distance (lastPoint, nextPoint);
// Cast a Ray forward for impact holes
var fRay = new Ray (lastPoint, Vector3((nextPoint.x - lastPoint.x), (nextPoint.y - lastPoint.y), (nextPoint.z - lastPoint.z)));
var fHits : RaycastHit[];
fHits = Physics.RaycastAll (fRay, dis);
for (var f=0; f<fHits.length; f++)
{
var fHit : RaycastHit = fHits[f];
var fOtherObj : GameObject = fHit.collider.gameObject;
var fHitPoint = fHit.point;
var fHitRotation = Quaternion.FromToRotation(Vector3.up, fHit.normal);
var fHole = Instantiate(bulletHole, fHitPoint, fHitRotation);
fHole.transform.parent = fHit.transform;
if (fOtherObj.collider.attachedRigidbody)
{
var direction = Vector3((nextPoint.x - lastPoint.x), (nextPoint.y - lastPoint.y), (nextPoint.z - lastPoint.z));
fOtherObj.collider.rigidbody.AddForceAtPosition(direction.normalized * 1000, fHitPoint);
}
if (fOtherObj.GetComponent(ObjectDestruction))
{
fOtherObj.GetComponent(ObjectDestruction).objectLife -= damage;
}
}
// Cast a Ray back for exit holes
var bRay = new Ray (nextPoint, Vector3((lastPoint.x - nextPoint.x), (lastPoint.y - nextPoint.y), (lastPoint.z - nextPoint.z)));
var bHits : RaycastHit[];
bHits = Physics.RaycastAll (bRay, dis);
for (var b=0; b<bHits.length; b++)
{
var bHit : RaycastHit = bHits[b];
var bOtherObj : GameObject = bHit.collider.gameObject;
var bHitPoint = bHit.point;
var bHitRotation = Quaternion.FromToRotation(Vector3.up, bHit.normal);
var bHole = Instantiate(exitHole, bHitPoint, bHitRotation);
bHole.transform.parent = bHit.transform;
}
if (leaveTracer == true)
{
visual.SetVertexCount (i + 1);
visual.SetPosition(i, nextPoint);
}
lastPoint = nextPoint;
}
}