- Home /
[resolved] Assign a lock target to a shoot
Hi I want to add a target at my shoot script (so, when I push Mouse1, the bullet is automatically direct on the target) , to do fight like mmorpg. But I'm noob in unity and for the moment I just have this basic script.
`
var Bullet : Transform;
var Speed = 16000;
var spawnPoint : Transform;
var RapidFire = false;
var SingleFire = true;
private var shooting = false;
var Counter = Time.deltaTime;
var RateOfFire = 0.250000;
function FixedUpdate ()
{
if(SingleFire==true){
if(Input.GetButtonUp("Fire1")){
var shot =Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity);
shot.rigidbody.AddForce(transform.forward * Speed); } }
if(RapidFire ==true){
if(Input.GetButtonDown("Fire1")){
shooting=true;
}
if(Input.GetButtonUp("Fire1")){
shooting=false;
}
if(shooting==true){ Counter += Time.deltaTime;
if(RateOfFireCounter){
var shotRapid =Instantiate(Bullet, spawnPoint.transform.position,
Quaternion.identity);
shotRapid.rigidbody.AddForce(transform.forward * Speed);
Counter=0; } } } }
thx for any help !
Is there just a single target or is the target some how acquired? Does the target move? Does your game have gravity? Do you want the target to get hit every time or just to shoot where the target is at the time the shot is made? Do you want a ballistic shell or do you want a seeker missile?
Is there just a single target or is the target some how acquired? -> 1 single target, (I'd like choose this target with a mouse1 click)
Does the target move? Yes
Does your game have gravity? No
Do you want the target to get hit every time or just to shoot where the target is at the time the shot is made? hit every time
Do you want a ballistic shell or do you want a seeker missile? I'd like something like a basic spell (imagine a fireball) in a classic mmo (wow, rift swtor, ect...)
Answer by DESTRUKTORR · May 05, 2013 at 12:59 PM
If you want Unity to register a click on a target, the simplest method I can think of would be to add a collider to your target object, first, then perform a raycast to ensure that you can reach it. Firstly, however, I'm going to cover some basics of code readability with you, so you can possibly receive faster answers, next time:
You don't have to put opening curlybraces on the next line (like I have, here), but the closing braces should always be on the next line after the last line in a block of code, assuming the block of code takes up multiple lines (a "block" of code is basically any code enclosed by curly-braces).
Indent each line by one tab per block containing it. For example, everything within a function should be indented at least one tab further thanthe function. If there is an if statement (or any other valid type of code-block) in that function, everything contained within that should be indented one tab more. If this isn't making much sense, take a look at the code I've rewritten for you, here:
var Bullet : Transform; var Speed = 16000; var spawnPoint : Transform; var RapidFire = false; var SingleFire = true; private var shooting = false; var Counter = Time.deltaTime; var RateOfFire = 0.250000; function FixedUpdate () { if(SingleFire==true) { if(Input.GetButtonUp("Fire1")) { var shot = Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity); shot.rigidbody.AddForce(transform.forward * Speed); } } if(RapidFire ==true) { if(Input.GetButtonDown("Fire1")) { shooting=true; } if(Input.GetButtonUp("Fire1")) { shooting=false; } if(shooting==true) { Counter += Time.deltaTime; if(RateOfFireCounter) { var shotRapid =Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity); shotRapid.rigidbody.AddForce(transform.forward * Speed); Counter=0; } } } }
Ok, now that we've gotten that nice and cleaned up, we can get to the source of the problem.
So, I'm assuming this script is attached to the player's GameObject
, so first thing's first, you'll want to change a few things around here to make this more reliable.
A little known secret about FixedUpdate- only use it if you need to use physics continuously on an object. I know some of the documentation might allude that it is intended for use with any object that will use physics, but if you're just applying force one time, it really won't make much difference, however FixedUpdate's biggest pitfalls lie in its ability to reliably register input (as it isn't called every frame). So our first step should be to fix that:
//Note that this is all I've changed, here.
function Update ()
{
if(SingleFire==true)
{
if(Input.GetButtonUp("Fire1"))
{
var shot = Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity);
shot.rigidbody.AddForce(transform.forward * Speed);
}
}
if(RapidFire ==true)
{
if(Input.GetButtonDown("Fire1"))
{
shooting=true;
}
if(Input.GetButtonUp("Fire1"))
{
shooting=false;
}
if(shooting==true)
{
Counter += Time.deltaTime;
if(RateOfFireCounter)
{
var shotRapid =Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity);
shotRapid.rigidbody.AddForce(transform.forward * Speed);
Counter=0;
}
}
}
}
Now for the hard part: actually checking for the target. Assuming that this isn't an FPS, and the mouse is free to move independently of the camera's movements, you'll have to do it like this:
function CheckClick()
{
if(shooting)
{
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
// you can set the 100 to whatever distance you want :P
if (Physics.Raycast(ray,hit,100))
{
var enemy = hit.transform.GetComponent(YourEnemyClass);
if(hit.transform.GetComponent(YourEnemyClass))
{
transform.LookAt(enemy);
}
}
}
}
So, at the very least, this is a start for achieving the goal you need for this. Depending on whether you want the player to be able to fire with or without targeting an enemy will define what we need to do, next.
If you don't want to be able to fire unless you've clicked on a target (similarly to an MMORPG, as you've stated you want this to function), you'll need to handle firing within this new function (which you could put in the update function, rather than writing a new function, but it's better programming practice to split up your code into multiple functions, especially if it's code you're using in the Update function, and is longer than 4-10 lines).
So, here's what we have so far, after moving the shooting handling over to the new function:
var bullet : Transform;
var speed = 16000;
var spawnPoint : Transform;
var rapidFire = false;
var counter = 0.0;
var rateOfFire = 0.25;
function Update ()
{
CheckClick();
}
function CheckClick()
{
if(Input.GetButtonDown("Fire1") || (rapidfire && Input.GetButton("Fire1"))
{
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
// you can set the 100 to whatever distance you want :P
if (Physics.Raycast(ray,hit,100))
{
var enemy = hit.transform.GetComponent(YourEnemyClass);
if(hit.transform.GetComponent(YourEnemyClass))
{
transform.LookAt(enemy);
HandleFiring();
}
}
}
}
function HandleFiring()
{
if(rapidFire)
{
counter += Time.deltaTime;
// I'm going to assume RateOfFireCounter is a variable that you've not shown here? Otherwise this won't do anything for you...
if(RateOfFireCounter)
{
var shotRapid =Instantiate(bullet, spawnPoint.transform.position, Quaternion.identity);
shotRapid.rigidbody.AddForce(transform.forward * speed);
Counter=0;
}
}
else
{
var shot = Instantiate(Bullet, spawnPoint.transform.position, Quaternion.identity);
shot.rigidbody.AddForce(transform.forward * speed);
}
}
I've changed a number of things, this time, as I didn't notice them before, but it's more or less more programming practice stuff.
Don't use more objects than you need. Wasting memory doesn't help anything, and just makes your code more complicated to read, and slower to run. I removed the
singleFire
boolean simply because I will assume that the weapon can only be rapid-fire or single-fire, since you've shown here with one of those boolean variables as true, and one as false. You only really need one boolean to represent that, since there's no third option. If there were a third option, I would suggest using an enum, rather than two booleans (since that would reduce the memory footprint of the resulting object), but I won't get into what an enum is, here. You'll have to do research on that one, yourself.Use
else if
statements if you're doing a chain of if statements and if the first one is true, the others won't be, and if the first is false, one of the others may be true. Additionally, use a simpleelse
statement if you want whatever you put in that block to run in any situation where the preceding if statement is not satisfied.Don't use
someBool == true
. Ever. If you put a boolean into an if statement, you don't need to check if it's true. That just performs an extra call that you don't need, plus it's extra typing that isn't necessary simplyif(someBool)
will suffice. If you want to check if a boolean is false, simply put an '!' before it, like thisif(!someBool)
.Don't capitalize variable names. Only capitalize function names and object type declarations (such as enums, or, in C#, classes, structs, and interfaces). Again, you don't really need to worry about what these are (if you were using any of them, believe me, you'd know). Generally, though, you shouldn't capitalize the first letter of a variable, but always do so with functions, in javascript, lol.
When declaring a float literal (such as
rateOfFire = 0.25
) there's no need to use extra 0s. It won't increase precision of the float. A float, in any programming language (at least as far as I know... there could be a freakish language out there that behaves differently, but I doubt it) will always have a fixed amount of memory available to it, and thus will always conform to a certain level of precision. Adding 0s does not improve that, it just... well... adds 0s :P.Don't use functions or other fields to assign variable fields (such as
var counter = Time.deltaTime;
, found at the beginning of this behaviour). Use literals, in these situations (`var counter = 0.0;`). Given that this will be initialized before the first Update call, it will either initialize to whatever Time.deltaTime initializes to. This is bad practice simply because there's really no reason to initialize it this way, and because we really don't know what that variable is, at that time. In fact, I'm not even sure that the compiler would let you do that... It certainly wouldn't if you were using C#.
That's all I can think of, for now, but let me know if this last version doesn't work. Good luck, and happy programming!
Answer by chewdri · May 05, 2013 at 03:16 PM
Ty a lot for your big answer, I tried to understand all of this (and trust me, its hard with the combo low in english + low in programming :D)
I just have a problem with "Yourenemyclass", actually i try this script with a static cube as ennemy and I dont know how to do this ennemy class and what code I have to put in this class.
YourEnemyClass
is not a real class. I just used that as a placeholder since I don't know what you named the class for your enemy's script. Basically, just replace every time you see YourEnemyClass
with whatever file name you used for your enemy's script.
Ok here is my edit script
var bullet : Transform; var speed = 16000; var spawnPoint : Transform; var rapidFire = false; var counter = 0.0; var rateOfFire = 0.25; var ennemydeux : Transform; function Update () { CheckClick(); } function CheckClick() { if(Input.GetButtonDown("Fire1") || (rapidFire && Input.GetButton("Fire1"))) { var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition); var hit : RaycastHit; // you can set the 100 to whatever distance you want :P if (Physics.Raycast(ray,hit,100)) { var enemy = hit.transform.GetComponent(ennemy); if(hit.transform.GetComponent(ennemy)) { transform.LookAt(ennemydeux); HandleFiring(); } } } } function HandleFiring() { if(rapidFire) { counter += Time.deltaTime; // I'm going to assume RateOfFireCounter is a variable that you've not shown here? Otherwise this won't do anything for you... if(rateOfFire) { var shotRapid =Instantiate(bullet, spawnPoint.transform.position, Quaternion.identity); shotRapid.rigidbody.AddForce(transform.forward * speed); Counter=0; } } else { var shot = Instantiate(bullet, spawnPoint.transform.position, Quaternion.identity); shot.rigidbody.AddForce(transform.forward * speed); } }
sorry or the presentation, but it's doing this when I cut and paste my code.
had some errors (I replace rapidFireConvert by rapidFire, I thought you made a mistake tell me if I'm wrong)
just put my Ennemy's script (its empty for now) on my cube
-When i try to play, nothing happend when I click with $$anonymous$$ouse1 (no spawn, no bullet)
Ok nvm, I forgot to put my script "ennemy" on my cube But it still dont work correctly
Now when I click with $$anonymous$$ouse1 on my cube, my character rotate 90° (not in the direction of the cube) the bullet spawn but dont shoot the cube, it just shot in front of my character.
I solved the problem yesterday,
var shot = Instantiate(bullet, spawnPoint.transform.position, Quaternion.identity);
shot.rigidbody.AddForce(transform.forward * speed);
shot.transform.LookAt(ennemydeux);
shot.transform.Translate(Vector3.forward*Speed*Time.deltaTime);
Destroy((shot.gameObject), 2);
Ty :)
Your answer
Follow this Question
Related Questions
Script for shooting a target 0 Answers
how to make a shooting target ? 2 Answers
how do i make it so when i click on an object it sets it as a variable 1 Answer
Shoot Ball in Direction a Target 1 Answer
Moving Enemies? 1 Answer