Hey, everybody. I have a gun script that is not working as expected. When I call transform.TransformDirection for raycasting, it goes to the side, not forward. the raycast function looks like this:
function Shoot(oneShot : boolean, isProjectile : boolean) //function shoot handles the shooting logic.
{
if(freeToShoot)
{
//gets vars for raycasting
var SAhit : RaycastHit;
var SAfwd = transform.TransformDirection(Vector3.forward);
PlayShotSound();
if(!unlimited)
{
shotsLeft--;//subtract one bullet
}
if(!isProjectile)
{
GenerateShotGraphics();
Debug.DrawRay(centerScreen.transform.position, SAfwd*gunRange, Color.blue);
if(Physics.Raycast(centerScreen.transform.position, SAfwd, SAhit, gunRange)) //The following lines are for raycasting. you can skip this if you want.
{
GenerateHitGraphics(SAhit, SAhit);
ApplyForce(SAhit);
}
if(oneShot)
{
freeToShoot = false;//if we are semi auto, dont keep fireing
}
} else
{
//Instantiates the projectile.
var instantiatedProjectile : Rigidbody;
instantiatedProjectile = Instantiate(projectilePrefab, centerScreen.transform.position, transform.rotation);
instantiatedProjectile.velocity = transform.TransformDirection(Vector3.forward * projectileShotPower);
if(shotType == ShotType.Semi_Auto)
{
freeToShoot = false;
}
}
}
}
The rest of the code looks like this:
//the enumeration storing the FireType info
enum FireType
{
RayCast,
Projectile
}
//the enumeration storing the ShotType info
enum ShotType
{
Semi_Auto,
Full_Auto,
}
//The number of clips the gun has
var Clips : int;
//The size of the clips
var clipSize : int;
//the boolean unlimited. If checked true, the gun will fire endless bullets
//good for power ups or testing
var unlimited : boolean = false;
//the boolean autoReload. if checked true, the gun will auto reload.
//using this and a small clip will make a burst type gun
var autoReload : boolean = true;
//the range of the gun. type "Infinity" if you want it to be infinite.
var gunRange : float;
//the fire rate of the gun
var fireRate : float;
// the projectile prefab. this will only affect the gun if the fireType is set to Projectile
var projectilePrefab : Rigidbody;
//the shot power. once again, this will only affect the gun if the fireType is set to Projectile
var projectileShotPower : float;
//the damage each shot deals
var Damage : int;
//the fire type variable. your choices are listed in the FireType enumeration above.
var fireType : FireType;
//the shot type variable. your choices are listed in the ShotType enumeration above.
var shotType : ShotType;
//the shot sound of the gun
var shotSound : AudioClip;
// the out of ammo sound of the gun
var OutOfAmmoSound : AudioClip;
//the reload sound of the gun
var reloadSound : AudioClip;
// the particle effects that the gun has. usually particles that look like bullets, or a muzzle flash
var ShotEmitter : ParticleEmitter[];
//the transform refrence to the tip of the gun
var tipOfGun : Transform;
// the transform refrence to the center of the sceen
var centerScreen : Transform;
//do we use the tag system?
var useTags : boolean = false;
//The following are the particles for different surfaces.
//Wood
var WoodParticle : GameObject;
//Metal
var MetalParticle : GameObject;
//Concrete
var ConcreteParticle : GameObject;
//Dirt
var DirtParticle : GameObject;
//Snow
var SnowParticle : GameObject;
//Water
var WaterParticle : GameObject;
// and last but most certainly not least, enemies
var EnemyParticle : GameObject;
//the array for using the non tag system.
var HParticles : GameObject[];
//the name of the gun
var gunName : String;
// the key pressed to access this gun. NOT THE KEY TO FIRE, but the key that when pressed and this gun is not the current gun, it activates this gun and deacivates all other guns in the gun manager
var keyToActivate : KeyCode;
//the bullet mark of the gun
var bulletMark : GameObject;
//Do we leave a bullet mark?
var leaveBM : boolean = false;
// the elapse for the reload
var reloadElapse : float;
//how much power this will have on rigidbodies
var pushPower : float;
//The icon for the gun Manager
var icon : Texture2D;
//@HideInInspector is a line used to make a public var not appear in the inspector.
// the shots left before the clip is empty
@HideInInspector
var shotsLeft : int;
// the audio source
private var Audio : AudioSource;
//can we currently shoot?
private var freeToShoot : boolean = true;
//can we currently reload?
private var freeToReload : boolean = true;
//the clips left before the gun is useless.
private var clipsLeft : int;
//should we be shooting?
private var shouldShoot : boolean = true;
//are we reloading?
private var reloading : boolean = false;
//the last shot time
private var lastShotTime : float;
//rlInt will be used for reloading
private var rlInt : float;
//We call On Enable instead of Awake becuase this object(Gun) will be enabled multiple times throughout the game.
function OnEnable()
{
//a for loop executes a certain line of code for a specified number of times.
//Unless writing very specific code, use only for arrays.
for(var i = 0; i < ShotEmitter.length; i++)
{
//sets the visual effects to off.
ShotEmitter*.emit = false;*
*}*
*//gets an audio source*
*Audio = gameObject.GetComponent(AudioSource);*
*//sets the shots left*
*shotsLeft = clipSize;*
*//sets the clips left*
*clipsLeft = Clips;*
*}*
*function Update ()*
*{*
*//The following lines are for checking if the user pressed fire.*
*//Full Auto, Raycast, and we can shoot again*
*if(Input.GetButton("Fire1") && shotType == ShotType.Full_Auto && fireType == FireType.RayCast && Time.time > lastShotTime)*
*{*
*lastShotTime = Time.time + fireRate;*
*Shoot(false, false);*
*} else if(Input.GetButtonDown("Fire1") && shotType == ShotType.Semi_Auto && fireType == FireType.RayCast) //Semi Auto, RayCast*
*{*
*Shoot(true, false);*
*} else if(Input.GetButtonDown("Fire1") && fireType == FireType.Projectile) //Projectile*
*{*
*Shoot(false, true);*
*} else if(Input.GetButton("Fire1") && shotType == ShotType.Full_Auto && fireType == FireType.Projectile && Time.time > lastShotTime)*
*{*
*lastShotTime = Time.time + fireRate;*
*Shoot(true, true);*
*} else {*
*freeToShoot = true;*
*}*
*if(shotsLeft <= 0 && autoReload) //if we auto reload*
*{*
*Reload();// reload*
*freeToShoot = false;//we can't shoot while reloading*
*}*
*if(clipsLeft == 0)*
*{*
*freeToReload = false;//if we don't have any more clips, then we can't reload*
*}*
*if(shotsLeft <= 0)*
*{*
*shotsLeft = 0;//if we don't have any more bullets, we can't shoot*
*freeToShoot = false;*
*}*
*HandleReloading();*
*}*
*function Shoot(oneShot : boolean, isProjectile : boolean) //function shoot handles the shooting logic.*
*{*
*if(freeToShoot)*
*{*
*//gets vars for raycasting*
*var SAhit : RaycastHit;*
*var SAfwd = transform.TransformDirection(Vector3.forward);*
*PlayShotSound();*
*if(!unlimited)*
*{*
*shotsLeft--;//subtract one bullet*
*}*
*if(!isProjectile)*
*{*
*GenerateShotGraphics();*
_Debug.DrawRay(centerScreen.transform.position, SAfwd*gunRange, Color.blue);_
*if(Physics.Raycast(centerScreen.transform.position, SAfwd, SAhit, gunRange)) //The following lines are for raycasting. you can skip this if you want.*
*{*
*GenerateHitGraphics(SAhit, SAhit);*
*ApplyForce(SAhit);*
*}*
*if(oneShot)*
*{*
*freeToShoot = false;//if we are semi auto, dont keep fireing*
*}*
*} else*
*{*
*//Instantiates the projectile.*
*var instantiatedProjectile : Rigidbody;*
*instantiatedProjectile = Instantiate(projectilePrefab, centerScreen.transform.position, transform.rotation);*
_instantiatedProjectile.velocity = transform.TransformDirection(Vector3.forward * projectileShotPower);_
*if(shotType == ShotType.Semi_Auto)*
*{*
*freeToShoot = false;*
*}*
*}*
*}*
*}*
*function GenerateHitGraphics(hit : RaycastHit, BMhit : RaycastHit) //HERE Is where we create the graphics for the HIT. NOT the SHOT!*
*{*
*//vars for the particles.*
*var go : GameObject;*
*var delta : float = -0.02;*
*var hitUpDir : Vector3 = hit.normal;*
*//leaves a bullet hole*
*if(leaveBM)*
*{*
*if(BMhit.collider.tag == "Wood" || "Metal" || "Concrete")*
*{*
*if(!BMhit.collider.rigidbody && !BMhit.collider.isTrigger)*
*{*
*var bm = Instantiate(bulletMark, BMhit.point, Quaternion.FromToRotation(Vector3.forward, -BMhit.normal));*
*bm.AddComponent(BulletMark);*
*}*
*} else {*
*return;*
*}*
*}*
*//sends the apply damage message to the enemy that we hit*
*if(hit.collider.tag == "Enemy")*
*{*
*hit.collider.SendMessageUpwards("ApplyDamage", Damage, SendMessageOptions.DontRequireReceiver);*
*}*
*if(useTags)*
*{*
*//changes the type of particle.*
*switch(hit.collider.tag)*
*{*
*case "Wood":*
*go = Instantiate(WoodParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "Metal":*
*go = Instantiate(MetalParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "Snow":*
*go = Instantiate(SnowParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "Concrete":*
*go = Instantiate(ConcreteParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "Dirt":*
*go = Instantiate(DirtParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "water":*
*go = Instantiate(WaterParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*case "Enemy":*
*go = Instantiate(EnemyParticle, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*
*break;*
*}*
*Destroy(go, go.gameObject.GetComponent(ParticleEmitter).maxEnergy);*
*} else {*
*for(i = 0; i < HParticles.length; i++)*
*{*
_var Go : GameObject = Instantiate(HParticles*, hit.point, Quaternion.FromToRotation(Vector3.forward, hitUpDir)) as GameObject;*_
_*Destroy(Go, Go.gameObject.GetComponent(ParticleEmitter).maxEnergy);*_
_*}*_
_*}*_
_*}*_
_*//here is where the shot graphics are made.*_
_*function GenerateShotGraphics()*_
_*{*_
_*//emits once the shot visual effects*_
_*for(var i = 0; i < ShotEmitter.length; i++)*_
_*{*_
<em>_ShotEmitter*.Emit();*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*//applys force to all rigidbodies that are hit.*_</em>
<em>_*function ApplyForce(hit : RaycastHit)*_</em>
<em>_*{*_</em>
<em>_*if(hit.collider.rigidbody)*_</em>
<em>_*{*_</em>
<em>_*var fwd = transform.TransformDirection(Vector3.forward);*_</em>
<em><em>_hit.rigidbody.AddForce(fwd * pushPower);_</em></em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*function HandleReloading()*_</em>
<em>_*{*_</em>
<em>_*if(Input.GetButtonDown("Fire2") || Input.GetKeyDown(KeyCode.R))*_</em>
<em>_*{*_</em>
<em>_*Reload();// pressed the reload button, reload.*_</em>
<em>_*}*_</em>
<em>_*if(reloading)*_</em>
<em>_*{*_</em>
<em>_*rlInt -= Time.deltaTime;*_</em>
<em>_*if(rlInt <= 0.0)*_</em>
<em>_*{*_</em>
<em>_*reloading = false;*_</em>
<em>_*shotsLeft = clipSize;*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*//the reload function.*_</em>
<em>_*function Reload()*_</em>
<em>_*{*_</em>
<em>_*if(clipsLeft > 0 && shotsLeft < clipSize)*_</em>
<em>_*{*_</em>
<em>_*PlayReloadSound();*_</em>
<em>_*reloading = true;*_</em>
<em>_*rlInt = reloadElapse;*_</em>
<em>_*}*_</em>
<em>_*if(!unlimited)*_</em>
<em>_*{*_</em>
<em>_*clipsLeft--;*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*function PlayShotSound()*_</em>
<em>_*{*_</em>
<em>_*Audio.PlayOneShot(shotSound);*_</em>
<em>_*}*_</em>
<em>_*function PlayOutOfAmmoSound()*_</em>
<em>_*{*_</em>
<em>_*Audio.PlayOneShot(OutOfAmmoSound, 1);*_</em>
<em>_*}*_</em>
<em>_*function PlayReloadSound()*_</em>
<em>_*{*_</em>
<em>_*Audio.PlayOneShot(reloadSound);*_</em>
<em>_*}*_</em>
<em>_*function GetBulletsLeft()*_</em>
<em>_*{*_</em>
<em>_*return(shotsLeft);*_</em>
<em>_*}*_</em>
<em>_*function GetName()*_</em>
<em>_*{*_</em>
<em>_*return(gunName);*_</em>
<em>_*}*_</em>
<em>_*function AddAmmo(amount : int)*_</em>
<em>_*{*_</em>
<em>_*clipsLeft += amount;*_</em>
<em>_*shotsLeft += amount;*_</em>
<em>_*}*_</em>
<em>_*```*_</em>