- Home /
transform.TransformDirection not working
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[i].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[i], 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++)
{
ShotEmitter[i].Emit();
}
}
//applys force to all rigidbodies that are hit.
function ApplyForce(hit : RaycastHit)
{
if(hit.collider.rigidbody)
{
var fwd = transform.TransformDirection(Vector3.forward);
hit.rigidbody.AddForce(fwd * pushPower);
}
}
function HandleReloading()
{
if(Input.GetButtonDown("Fire2") || Input.GetKeyDown(KeyCode.R))
{
Reload();// pressed the reload button, reload.
}
if(reloading)
{
rlInt -= Time.deltaTime;
if(rlInt <= 0.0)
{
reloading = false;
shotsLeft = clipSize;
}
}
}
//the reload function.
function Reload()
{
if(clipsLeft > 0 && shotsLeft < clipSize)
{
PlayReloadSound();
reloading = true;
rlInt = reloadElapse;
}
if(!unlimited)
{
clipsLeft--;
}
}
function PlayShotSound()
{
Audio.PlayOneShot(shotSound);
}
function PlayOutOfAmmoSound()
{
Audio.PlayOneShot(OutOfAmmoSound, 1);
}
function PlayReloadSound()
{
Audio.PlayOneShot(reloadSound);
}
function GetBulletsLeft()
{
return(shotsLeft);
}
function GetName()
{
return(gunName);
}
function AddAmmo(amount : int)
{
clipsLeft += amount;
shotsLeft += amount; }
Answer by Eric5h5 · Apr 03, 2011 at 09:26 PM
Instead of transform.TransformDirection(Vector3.forward), you can just do transform.forward.
Answer by zmar0519 · Apr 03, 2011 at 08:25 PM
Sorry, solved. I changed Vector3.forward to Vector3.left.
Turns out that forward really is supposed to be forward. Unity thinks +Z is forwards. You apparently think +X is forward. Only real problem is that LookAt faces you along +Z, so you may have to twist it 90degs.
Your answer
![](https://koobas.hobune.stream/wayback/20220613120543im_/https://answers.unity.com/themes/thub/images/avi.jpg)