I do? I just do the if statement every frame…checking if the method is allready running (isAiming). By setting the bool to true it should be executed only once as far as I know.
@Rob21894 I want to use the mouse to charge up the bow. In the end a kind of energy bar filling up and getting low again.
So the Player has to do the right timing.
→ Need to check every frame for the mouseclick → charge up and down the energy bar (endless till mouse is released)–> get a strength number at mouse relase
While() is dangerous in Unity. It freeze all other code execution for most scripts.
Update() is running once per Frame and each instance is checking if the mouse is held down.
I’d need to see more code. The above isn’t right.
You probably want to us Input.GetMouseButtonDown(1) for the first frame the user pressed it. And Input.GetMouseButtonUp(1) for the first frame they released it.
This should be all relevant code, like I said the freeze is definetly caused by the quoted line:
while(Input.GetMouseButton(1))
@Lloyd_RedironLabs : So there are issues with the while? Sadly expected that …how can I do it otherwise?
How can I check for the mouse release/press just the frame its done? O.o
Expected I would have to check it every frame…like I do with keyboardinputs 2.
Still new to unity - sounds like I missed something important there?
The problem with those loops is that it’s impossible for it to stop. If Input.GetMouseButton(1) is true, then Input.GetMouseButtonUp(1) can’t be true, so you never hit the breaks. You can’t hold down the mouse button and release it at the same time.
The 2-player tank tutorial actually does something very similar to what you’re trying to do. You should check it out.
No worries, in Unity, just know you almost never want to use a While loop. While is dangerous, should only be used in Co-routines or when you are certain you want to halt execution, and have escape procedures.
I’d probably do something like this:
using System;
using UnityEngine;
public class Archery : MonoBehaviour
{
/// <summary>
/// Define some states for the archer
/// </summary>
public enum ArcherState
{
Rest,
Reload,
Fire,
Aim,
None
}
// What prefabs do we have?
public GameObject ArrowPrefab;
// What state are we in?
private ArcherState currentState = ArcherState.Rest;
private ArcherState lastState = ArcherState.None;
private Animator animamatorReference;
private float firingPower = 0f;
public int arrows = 10;
// Setup our scene
void Start()
{
animamatorReference = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(1))
currentState = ArcherState.Aim;
if (Input.GetMouseButtonUp(1))
currentState = ArcherState.Fire;
if (Input.GetKey(KeyCode.Q))
currentState = ArcherState.Reload;
if (currentState != lastState)
{
// the state has changed, time to change our animation
AnimateArcher();
if (currentState != lastState)
Debug.Log(name + "::Upddate > Archer animation state changed to " + currentState.ToString());
}
// Execute our aiming, firing, reload, etc
RunActions();
// Update our reference, so we can determine if a state is "held" or if a a state is "new".
lastState = currentState;
}
void RunActions()
{
// What state is the character currently in?
switch (currentState)
{
case ArcherState.Aim:
// Execute every time
IncreasePower();
break;
case ArcherState.Reload:
// Only execute once
if (currentState != lastState)
Reload();
// Then back to resting
currentState = ArcherState.Rest;
break;
case ArcherState.Fire:
// Only execute once
if (currentState != lastState)
Fire();
// Then back to resting
currentState = ArcherState.Rest;
break;
}
}
void IncreasePower()
{
float minPower = 10f;
float maxPower = 100f;
firingPower = Mathf.Clamp(firingPower += 1f, minPower, maxPower);
}
void Fire()
{
// Ammo?
if (arrows == 0)
return;
// Fire prefab
var fireArrow = GameObject.Instantiate(ArrowPrefab);
if (fireArrow != null)
{
fireArrow.transform.rotation = transform.rotation;
fireArrow.transform.position = transform.position;
// Get or add a rigid body for phyiscs
var fireArrowRigid = fireArrow.GetComponent<Rigidbody>();
if (fireArrowRigid == null)
fireArrowRigid = fireArrow.AddComponent<Rigidbody>();
// then apply rigidbody or whatever with a direction of transform.position.forward against the firing power;
fireArrowRigid.useGravity = true;
fireArrowRigid.velocity = fireArrow.transform.forward * firingPower;
firingPower = 0f;
}
// Use up ammo
arrows -= 1;
}
void Reload()
{
// Reload
arrows = 10;
}
void AnimateArcher()
{
// Animate based on the characters state
}
}
That uses a mini state-machine for the archer, and will lob objects at a distance based on the power.
That was really easy to read and understand - and as far as I know thats the most important thing to be a really good programmer. Thanks for your work!
The Math.Clampf will help a lot! So I don’t have to struggle with booleans for max and min and with the state machine I can say goodbye to the while. I ll try to keep the machine in my memory.
Is the structur done by your comments a usual blueprint you are following? Or just best fitting in this case?
Just for this case…
Usually I would split building/continuous actions and one-shot actions. But because this one was easy to keep them coupled it just made sense.
If you get stuck just holler
But this is representative of a lot of one off objects in my game worlds.