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\$

2 Answers 2

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\$
2
  • \$\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
    Commented Nov 17, 2016 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
    Commented Nov 17, 2016 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\$
2
  • 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
    Commented Nov 16, 2016 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
    Commented Nov 17, 2016 at 3:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .