- Home /
How can I tell if I fired an arrow in another script?
I'm trying to make a first-person RPG that uses an X-Box One controller. I'm trying to set up arrow firing for combat. Currently, whenever I use the right trigger to fire the arrow, the editor freezes. I think it's an infinite loop somewhere. The player Instantiates the arrow to start. The logic should go as follows: Trigger is pressed. As the bool fired in player is true and all conditions are met, the arrow is instantiated, and Player's fired is set to false, to stop it from firing repeatedly. ArrowMover's fired bool is set to false as long as the trigger is held. While the trigger is held, arrowPower increases by drawStrength until it reaches maximumDraw or trigger is released. Then, when trigger is released, ArrowMover's fired is set to true, force equal to arrowPower is added to the arrow, and Player's Fired() function is called. Fired() makes player's fired true, so another arrow can be fired. Or at least that's how it should work. Any suggestions or questions?
The scripts are as follow.
ArrowMover Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class ArrowMover : MonoBehaviour {
//public float arrowSpeed;
public Rigidbody rb;
public float arrowPower;
public float maximumDraw;
public float rightTrigger;
public float pullStrength;
public bool fired;
//public static bool fired;
// Use this for initialization
void Start () {
fired = false;
Debug.Log("2");
rightTrigger = CrossPlatformInputManager.GetAxis("RightTrigger");
while (fired == false)
{
Debug.Log("3");
while (rightTrigger == 1)
{
Debug.Log("4");
if (arrowPower <= maximumDraw)
{
arrowPower += pullStrength;
}
else
{
arrowPower = maximumDraw;
}
}
fired = true;
}
rb.AddForce(transform.forward * arrowPower);
Debug.Log("5");
Player.player.Fired();
}
// Update is called once per frame
void Update () {
}
}
Player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class Player : MonoBehaviour {
public static Player player;
public GameObject Arrow;
public bool isMelee;
public int arrows;
public bool isBlocking;
public float walkingSpeed;
float leftHorizontal;
float leftVertical;
public bool onGround;
public float jumpHeight;
public Rigidbody rb;
public float turnSpeed;
float rightHorizontal ;
float leftTrigger;
float rightTrigger;
public bool fired = true;
void Start()
{
player = this;
rb = GetComponent<Rigidbody>();
}
void Update ()
{
rightHorizontal = CrossPlatformInputManager.GetAxis("RightHorizontal")*turnSpeed;
transform.Rotate(0, rightHorizontal, 0);
leftHorizontal = CrossPlatformInputManager.GetAxis("LeftHorizontal");
leftVertical = CrossPlatformInputManager.GetAxis("LeftVertical");
transform.position += (transform.right * leftHorizontal + transform.forward * leftVertical).normalized * walkingSpeed * Time.deltaTime;
if (Input.GetButtonDown("Jump") && onGround == true)
{
rb.AddForce(Vector3.up * jumpHeight);
}
isBlocking = false;
rightTrigger = CrossPlatformInputManager.GetAxis("RightTrigger");
if (rightTrigger == 1)
{
Debug.Log("Attack");
Attack();
}
leftTrigger = CrossPlatformInputManager.GetAxis("LeftTrigger");
if (leftTrigger == 1)
{
isBlocking = true;
}
}
void Attack()
{
if(isMelee == false && arrows >=1 && fired==true)
{
Debug.Log("1");
fired = false;
Instantiate(Arrow, transform.position, transform.rotation);
arrows--;
}
if(isMelee == true)
{
}
}
public void Fired()
{
fired = true;
}
}
Answer by jandd661 · Sep 14, 2018 at 03:05 PM
Check the ArrowMover Script. Make sure what you have in the Start() method is not supposed to be in Update() or somewhere else.
I'm pretty sure it's all supposed to be in the start script, since I'm using while loops.
Greetings, I'll be honest, I really don't like they way this is set up. The Start() method runs only once and on a instantiated object, will be befor the next Update() of the game. That means there is no update to input status while Start() is executing. From the docs: "Note also that the Input flags are not reset until "Update()", so its suggested you make all the Input Calls in the Update Loop."
https://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html https://docs.unity3d.com/ScriptReference/Input.html
That means while (rightTrigger == 1)
will always be 1
and the cause of your infinite loop.
Also understand that while loops not in a coroutine must complete before the game moves on to the next frame. In many cases (not all) a Coroutine can be used ins$$anonymous$$d of a while loop for better performance and reliability.
To answer your specific question, use this:
GameObject theArrow = Instantiate(Arrow, transform.position, transform.rotation);
That will give you a reference to the instantiated object.
So, I've changed the arrow script to this, which seems to work (or at least doesn't stop working) although fired becomes true until I press the trigger again ins$$anonymous$$d of directly after firing, which I'd like to fix. How do I use the reference? And, is there a way to keep the arrow from falling until it's fired.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class Arrow$$anonymous$$over : $$anonymous$$onoBehaviour {
//public float arrowSpeed;
public Rigidbody rb;
public float arrowPower;
public float maximumDraw;
public float rightTrigger;
public float pullStrength;
public bool fired;
//public static bool fired;
// Use this for initialization
void Start() {
fired = false;
}
// Update is called once per frame
void Update () {
rightTrigger = CrossPlatformInput$$anonymous$$anager.GetAxis("RightTrigger");
if (fired == false)
{
if (rightTrigger == 1)
{
if (arrowPower <= maximumDraw)
{
arrowPower += pullStrength;
}
else
{
arrowPower = maximumDraw;
}
}
if (rightTrigger == 0)
{
fired = true;
}
}
if (fired == true)
{
Debug.Log("fired = true");
fired = false;
rb.AddForce(transform.forward * arrowPower);
Player.player.Fired();
}
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Check to see if any bool instance is true? 1 Answer
Can't use script name as variable type? 2 Answers
How Can I Make My Fire Effect Disappear After I Shoot Object? 1 Answer