0
\$\begingroup\$

So what I am trying to achieve is have the player shoot toward the mouse positiion and I have that working but I want the player to have to charge their shot. So if the player just presses the button it only goes a certain distance but if the player holds the button down for a bit it goes farther.

I tried to make a video that kinda explains what I am going for.

This is the code that controls the shooting

public class BowController : MonoBehaviour {

    public GameObject arrow;
    public Transform shootLoc;

    public float force;
    public Camera cam;

    public float chargeMin;
    public float chargeAmount;
    public float chargeMax;

    public bool charging;



    void Start () {

    }


    void Update () {

        Ray cameraRay = cam.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        Vector3 pointToLook;

        if (Physics.Raycast(cameraRay, out hit, 50))
        {
            pointToLook = hit.point;
            Debug.DrawLine(cameraRay.origin, pointToLook, Color.blue);

        }
        else
        {
            pointToLook = cameraRay.origin + (cameraRay.direction * 50);
        }
        transform.LookAt(pointToLook);

        if(Input.GetMouseButtonDown(0))
        {
            charging = true;

        }
        if (charging)
        {
            Charging();
        }


        if (Input.GetMouseButtonUp(0))
        {
            GameObject tempArrow;
            tempArrow = Instantiate(arrow, shootLoc.position, shootLoc.rotation) as GameObject;

            tempArrow.transform.LookAt(pointToLook);

            Rigidbody tempBody;
            tempBody = tempArrow.GetComponent<Rigidbody>();

            tempBody.AddForce(transform.forward * force, ForceMode.Impulse);

            force = 100;
            charging = false;
        }
    }

    void Charging()
    {
        force += Time.deltaTime * chargeAmount;

        if (force >= 500)
        {
            force = 500;
        }
    }
}

And this is the code that is on the arrow

  public Rigidbody rBody;
  public float speed;

    void Awake () {
        flying = true;
    }


    void Update () {
        if (flying)
        {

            //rBody.velocity = rBody.velocity.normalized * speed;
            transform.LookAt(transform.position - GetComponent<Rigidbody>().velocity);
            transform.Rotate(0, 180, 0);
        }
    }

    void FixedUpdate()
    {

        /*
        if (flying)
        {
            transform.rotation = Quaternion.LookRotation(rBody.velocity);
        }
        */
    }

    void OnCollisionEnter(Collision collision)
    {
        flying = false;
    }
}

I am still pretty new to coding so any help is appreciated. Thank you all very much in advance for the help!

\$\endgroup\$
1
\$\begingroup\$

I'm unfamiliar with Unity, so this answer may not be specific enough, but the general way I'd do this is:

  • when the player initially clicks, save the timestamp (chargeStart)
  • When they release, take the current timestamp (chargeStop)
  • Subtract the difference to determine the length of the charge (chargeLength = chargeStop - chargeStart)
  • Based on a formula that has the desired effect (play around with this based on your desired end result), use chargeLength to increase the amount of force used on the projectile
\$\endgroup\$
  • \$\begingroup\$ So the problem is not the charging functionality because I have that working it is that no matter what force or charge time it always goes the same distance. \$\endgroup\$ – Cody Nov 17 '16 at 3:44
  • \$\begingroup\$ @Cody - What's the value of chargeAmount? Are you sure it's not making your force value exceed the 500 threshold you've set? If you set force as a constant before you apply the impulse, does it have the same effect? \$\endgroup\$ – darkside Nov 17 '16 at 16:18
-1
\$\begingroup\$

I would say that darkside's answer is probably what I would do. Just to add a little, in Unity you would probably use Time.time at the point where you start and finish charging. Additionally, Its probably a good idea to use Mathf.clamp(or just an if statement) to stop the charge reaching absurdly high levels. Anyway, just my two cents.

Good luck with the programming :)

\$\endgroup\$
  • 1
    \$\begingroup\$ This seems like more of a comment than an answer; perhaps you could detail how one would use Time.time and Mathf.Clamp. \$\endgroup\$ – Gnemlock Nov 16 '16 at 21:43
  • \$\begingroup\$ The charging functionality works fine. The force goes up when holding the button and I put a limit on how far it can go and after release, it goes to the starting force again. The problem I have is that it always goes the same distance and that is not what I am trying to achieve. I want the longer they charge to control the distance of the shot. \$\endgroup\$ – Cody Nov 17 '16 at 3:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.