- Home /
2D platformer firing left and right, help!
Hi all I'm trying to make a 2D platformer where I have a ninja character that throws shurikens, the problem I am having is that I can't figure out how to get my shuriken to fire right when facing right and fire left when facing left.
I've made some progress thanks to this site but i'm stumped and trying to search for the solution for 3 days my head is scrambled lol any help appriciated.
I'm making the game for android so it has touch controls for left and right movement, one for jump, and a button I made for firing the shurikens.
I have a empty object as a child to my character controller "shuriken_launcher" with my shoot script attched, the movement script is on my character controller "Player".
I have this code to shoot:
private var ray : Ray;
private var rayCastHit : RaycastHit;
var rocket : Rigidbody;
//var spawnRightObject : GameObject;
var shootforce:float;
//var mySound: AudioClip;
//function Start()
// {
// spawnRightObject = GameObject.Find("shuriken_launcher");
// }
function Update(){
if(Input.GetMouseButtonDown(0)){
ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, rayCastHit)){
if(rayCastHit.transform.name == "fire_button"){
Debug.Log("fire button hit");
//audio.clip = mySound;
//audio.Play();
var rocketClone : Rigidbody = Instantiate(rocket, transform.localPosition, transform.localRotation);
rocketClone.velocity = transform.forward * shootforce;
}
}
}
}
and this code to control my character:
public var skin : GUISkin; //GUI skin
public var mesh : GameObject; //Mesh
public var texMove : Texture2D[]; //Move texture
public var texJump : Texture2D; //Jump texture
public var audioJump : AudioClip; //Jump sound
public var audioDead : AudioClip; //Dead sound
private var selectedTex : int; //Selected texture
public var texUpdateTime : float; //Texture update time
private var tmpTexUpdateTime : float; //Tmp texture update time
public var moveSpeed : float; //Move speed
public var jumpSpeed : float; //Jump speed
public var gravity : float; //Gravity
private var dir : Vector3; //The direction the player is movin
private var rightTouchPad : GameObject; //Right touchpad
private var leftTouchPad : GameObject; //Left touchpad
var dead = false; //Are we dead
private var controller : CharacterController; //The character controller
var respawn : Transform; //respawn point
var Ninja : GameObject; //player
public var shuriken_launcher : GameObject;
//try to add in ducking later...public var crouch : Texture2D;
function Start ()
{
//Find the character controller
controller = GetComponent(CharacterController);
//Screen orientation to landscape left
Screen.orientation = ScreenOrientation.LandscapeLeft;
//Find left touchpad
leftTouchPad = GameObject.Find("LeftTouchPad");
//Find right touchpad
rightTouchPad = GameObject.Find("RightTouchPad");
//Start SetupJoysticks
StartCoroutine("SetupJoysticks");
//Set sleep time to never
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
function Update ()
{
//If we are not dead
if (!dead)
{
//Update
MoveUpdate();
TexUpdate();
}
}
function MoveUpdate()
{
//If we hit a object
var hit : RaycastHit;
if (Physics.Raycast(transform.position, Vector3.up, hit, 0.5f))
{
//If it is not the player
if (hit.transform.gameObject.tag != "goal")
{
//Set dir y to -1
dir.y = -1;
}
}
//If we are grounded
if (controller.isGrounded)
{
//If the game is not running on a android device
if (Application.platform != RuntimePlatform.Android)
{
//Set dir x to Horizontal
dir.x = Input.GetAxis("Horizontal") * moveSpeed;
//If we get Space key down
if (Input.GetKeyDown(KeyCode.Space))
{
//Set dir y to jumpSpeed
dir.y = jumpSpeed;
//Play jump sound
audio.clip = audioJump;
audio.Play();
}
}
//If the game is running on a android device
else
{
//Get left touchpad position x
var pX = leftTouchPad.GetComponent(Joystick).position.x;
//Get left touchpad tap count
var tC = rightTouchPad.GetComponent(Joystick).tapCount;
//Set dir x to touchpad x position
dir.x = pX * moveSpeed;
//If touchpad tap count are not 0
if (tC != 0)
{
//Set dir y to jumpSpeed
dir.y = jumpSpeed;
//animation.Play("somersault");
//Play jump sound
audio.clip = audioJump;
audio.Play();
}
}
}
//If we are not grounded
else
{
//Set dir y to gravity
dir.y -= gravity * Time.deltaTime;
}
//Move the player
controller.Move(dir * Time.smoothDeltaTime);
}
function TexUpdate()
{
//If we are not grounded
if (!controller.isGrounded)
{
//Set main texture to jump texture
mesh.renderer.material.mainTexture = texJump;
return;
}
//If the game is not running on a android device
if (Application.platform != RuntimePlatform.Android)
{
//Get Horizontal
var h = Input.GetAxis("Horizontal");
//If Horizontal is not 0
if (h != 0)
{
//If Horizontal is bigger than 0
if (h > 0)
{
//Set scale to 1,1,1
mesh.transform.localScale = Vector3(1,1,1);
shuriken_launcher.transform.localPosition = Vector3(0.5,-0.748386,0);
}
//If Horizontal is less than 0
else
{
//Set scale to -1,1,1
mesh.transform.localScale = Vector3(-1,1,1);
shuriken_launcher.transform.localPosition = Vector3(-0.5,-0.748386,0);
}
}
//If Horizontal is 0
else
{
//Set main texture to move texture
mesh.renderer.material.mainTexture = texMove[0];
return;
}
}
//If the game is running on a android device
else
{
//Get left touchpad x position
var pX = leftTouchPad.GetComponent(Joystick).position.x;
//If touchpad x position is not 0
if (pX != 0)
{
//If touchpad x position is bigger than 0
if (pX > 0)
{
//Set scale to 1,1,1
mesh.transform.localScale = Vector3(1,1,1);
}
//If touchpad x position is less than 0
else
{
//Set scale to -1,1,1
mesh.transform.localScale = Vector3(-1,1,1);
}
}
else
{
//Set main texture to move texture
mesh.renderer.material.mainTexture = texMove[0];
return;
}
}
//If tmpTexUpdateTime is bigger than texUpdateTime
if (tmpTexUpdateTime > texUpdateTime)
{
//Set tmpTexUpdateTime to 0
tmpTexUpdateTime = 0;
//Add one to selectedTex
selectedTex++;
//If selectedTex si bigger than texMove.Length - 1
if (selectedTex > texMove.Length - 1)
{
//Set selectedTex to 0
selectedTex = 0;
}
//Set main texture to move texture
mesh.renderer.material.mainTexture = texMove[selectedTex];
}
else
{
//Add 1 to tmpTexUpdateTime
tmpTexUpdateTime += 1 * Time.deltaTime;
}
}
function OnTriggerEnter(other : Collider)
{
//If we are in a enemy trigger
if (other.tag == "Enemy")
{
//Play dead sound
audio.clip = audioDead;
audio.Play();
//Dont show renderer
mesh.renderer.enabled = false;
//Kill
dead = true;
//testing respawn
//wait for 1 second
yield WaitForSeconds(1);
//take a life off lives
lives_counter.Counter -= 1;
//turn back on mesh renderer with a few flashes first
mesh.renderer.enabled = true;
yield WaitForSeconds(0.1);
mesh.renderer.enabled = false;
yield WaitForSeconds(0.1);
mesh.renderer.enabled = true;
mesh.renderer.enabled = true;
yield WaitForSeconds(0.1);
mesh.renderer.enabled = false;
yield WaitForSeconds(0.1);
mesh.renderer.enabled = true;
//make dead false again
dead = false;
}
}
// function OnGUI()
// {
// GUI.skin = skin;
//Menu Button
// if(GUI.Button(new Rect(Screen.width - 120,0,120,40),"Menu"))
// {
// Application.LoadLevel("Menu");
// }
//If we are dead
// if (dead)
// {
//Play Again Button
// if(GUI.Button(new Rect(Screen.width / 2 - 90,Screen.height / 2 - 60,180,50),"Play Again"))
// {
// Application.LoadLevel("Game 3");
// }
//Menu Button
// if(GUI.Button(new Rect(Screen.width / 2 - 90,Screen.height / 2,180,50),"Menu"))
// {
// Application.LoadLevel("Menu");
// }
// }
// }
function SetupJoysticks()
{
//Set touchpad position
leftTouchPad.transform.position = Vector3(0,0,0);
rightTouchPad.transform.position = Vector3(1,0,0);
//Wait 1 second
yield WaitForSeconds(1);
//Start the touchpads
leftTouchPad.GetComponent(Joystick).StartGame();
rightTouchPad.GetComponent(Joystick).StartGame();
}
Answer by fueldown · Jun 03, 2013 at 07:17 PM
instead of using transform.Forward, you should do something like this:
shootDirection = transform.parent.TransformDirection(Vector3.forward);
rocketClone.velocity = shootDirection * shootforce;
Again, this is untested, but should work. I didn't review full player script, but assuming shuriken_launcher is child of player, this script should throw shurikens in the direction the player is facing.
I get this error (if i make a var for shootDirection to correct this I don't get how that would shoot in the direction of the player facing) or am on the wrong track?
Assets/Game 3/Script/Javascript/throw_shuriken.js(27,5): BCE0005: $$anonymous$$ identifier: 'shootDirection'.
make it Vector3, not var. And, what that statement does, is it gives you the local forward direction of parent of your shuriken thrower, i.e. your ninja. Also, ignore the second line, it won't compile. my bad. use the following code ins$$anonymous$$d.
rocketClone.AddForce(shootDirection*shootforce, Force$$anonymous$$ode.Impulse);
let me know if it works for you.
rocketClone.velocity += shootDirection * shootforce;
you can use this as well. $$anonymous$$ake sure you do all physics in FixedUpdate.
I used the second version you supplied, it's kind of working as when I move my character left and right the shurikens instantiate left and right (but in the position you see in the attached image)
If you look at the attached picture they are going downwards (I have gravity turned off on them)
On my character controller script (with help from another answer on here) these lines of code move the shuriken_launcher with my character controller:
//If Horizontal is bigger than 0
if (h > 0)
{
//Set scale to 1,1,1
mesh.transform.localScale = Vector3(1,1,1);
**shuriken_launcher.transform.localPosition = Vector3(0.264756,-0.748386,0);**
}
//If Horizontal is less than 0
else
{
//Set scale to -1,1,1
mesh.transform.localScale = Vector3(-1,1,1);
**shuriken_launcher.transform.localPosition = Vector3(-0.5,-0.748386,0);**
}
}
This is my shootscript (attached to my shuriken_launcher object:
private var ray : Ray;
private var rayCastHit : RaycastHit;
var rocket : Rigidbody;
//var spawnRightObject : GameObject;
var shootforce:float;
//var mySound: AudioClip;
//function Start()
// {
// spawnRightObject = GameObject.Find("shuriken_launcher");
// }
function Update(){
if(Input.Get$$anonymous$$ouseButtonDown(0)){
ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, rayCastHit)){
if(rayCastHit.transform.name == "fire_button"){
Debug.Log("fire button hit");
//audio.clip = mySound;
//audio.Play();
var rocketClone : Rigidbody = Instantiate(rocket, transform.localPosition, transform.localRotation);
var shootDirection = transform.parent.TransformDirection(Vector3.forward);
//rocketClone.AddForce(shootDirection*shootforce, Force$$anonymous$$ode.Impulse);
rocketClone.velocity += shootDirection * shootforce;
}
}
}
}
thankyou for helping me with this I appriciated it :)
if you don't want the shurikens to obey gravity, you can use Force$$anonymous$$ode.Acceleration ins$$anonymous$$d, so that they will move with constant force like rockets or bullets. Also, I didn't quite understand how your launcher follows the character controller with that code. You should be able to achieve the effect by just making the launcher a child of character gameobject, or in script, with following simple code.
//declare public gameobject, drop your character in editor.
var characterObject : GameObject;
//use this in update.
transform.position = characterObject.transform.position;
transform.rotation = characterObject.transform.rotation;
// if you use this, you should be able to use this to know //which way to throw shurikens.
Vector3 shootDirection = transform.TransformDirection(Vector3.forward);
One tip: try declaring your variables in start and use them in updates. creating new variables in every frame can be very bad for cpu. Also, any physics calculations should be done in FixedUpdate.