[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 !

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:

  1. 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).

  2. 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.

  1. 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.
  2. 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 simple else statement if you want whatever you put in that block to run in any situation where the preceding if statement is not satisfied.
  3. 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 simply if(someBool) will suffice. If you want to check if a boolean is false, simply put an ‘!’ before it, like this if(!someBool).
  4. 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.
  5. 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.
  6. 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!

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.