State of Handles.RotationHandle() - unity3d

Can I somehow find out is it the first frame the user click on rotater, last frame or middle?
Handles.RotationHandle(...)
or
Handles.PositionHandle(...)
I need to know when the user start rotating/moving and when stop it.

Then you just need to add a variable to save the state. Something like this:
bool rotating;
void Update () {
if (rotating != Handles.RotationHandle(..)) {
rotating = !rotating;
if (rotating) {
//start rotation
} else {
//just stopped
}
} else if (rotating) {
//in rotating
}
}

Related

The punching bool is not setting the animation variable to true to false

In a nutshell, I want to code a punching script where every time the player presses a j key, the punching animation gets played. The issue is that the punching animation is not playing. Here is my code along with my screenshots with the Animator, and my animation for the punching animation.
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.J)) // attack
{
print("Times they have punched");
punching = true;
ispunching(punching);
} else
{
punching = false;
ispunching(punching);
}
}
void ispunching(bool punch)
{
if(punch)
{
print("Punching: " + punch);
anim.SetBool("Punch", punch);
waittilpunchanimfinish(1f);
}
else if (!punch)
{
print("Not punching" + punch);
anim.SetBool("Punch", punch);
}
}
IEnumerator waittilpunchanimfinish(float time)
{
yield return new WaitForSeconds(time);
punching = false;
}
Here is the image right here. I know the idle animation is not transitioned to the punching. I did it on purpose to simplify things so people can fix it easier :
The Punching Animation Picture Keyframe
In Update you do
if(Input.GetKeyDown(KeyCode.J)) // attack
{
print("Times they have punched");
punching = true;
ispunching(punching);
} else
{
punching = false;
ispunching(punching);
}
and thereby immediately reset the punching to false in the next frame where GetKeyDown will not be true anymore!
I would instead rather do the entire punch routine inside of the Coroutine like
// The only purpose left for this flag is for not having multiple
// Corouintes at the same time.
private bool punching;
private void Start()
{
anim = GetComponent<Animator>();
}
private void Update()
{
// Only receive input if not already punching
if(!punching && Input.GetKeyDown(KeyCode.J)) // attack
{
StartCoroutine(Punch());
}
}
// Handle the entire punch routine in one go
private IEnumerator Punch()
{
print("Start punching");
punching = true;
anim.SetBool("Punch", true);
yield return new WaitForSeconds(1f);
anim.SetBool("Punch", false);
punching = false;
print("Finished punching");
}

How to stop sprite animation at start in Flutter Flame game engine

I want to render this card and the first time it's loaded, the animation start once. What I want is the default there is no animation happen. Does anyone know how to make this happen?
class Card extends AnimationComponent {
Card(width, height)
: super.sequenced(width, height, 'card.png', 5,
textureWidth: 144.0, textureHeight: 220.0, loop: false);
}
class GameScreen extends BaseGame {
GameScreen({#required this.size}) {
add(Card(0,0));
}
}
According to the source code, you'll able to use Animation to control the frame.
For simple, just don't call update and keep rendering, the frame index will not be updated.
void update(double dt) {
clock += dt;
elapsed += dt;
if (isSingleFrame) {
return;
}
if (!loop && isLastFrame) {
onCompleteAnimation?.call();
return;
}
while (clock > currentFrame.stepTime) {
if (!isLastFrame) {
clock -= currentFrame.stepTime;
currentIndex++;
} else if (loop) {
clock -= currentFrame.stepTime;
currentIndex = 0;
} else {
break;
}
}
}
So you could just override the update method to get the controll of sprite animations.

How do I get perform a single button press to call a method?

I would like a Unity progress slider to fill up when I press the spacebar. Currently, I have to mash the spacebar 100 times to fill up the progress bar.
It fills the progress slider automatically when moved to update().
It fills the progress slider when I hold the spacebar if I change Input.GetKeyDown to Input.GetKey.
But I don't want to hold the spacebar down. I want to press it once to start have the slider value gradually fill up the progress bar.
void Start()
{
sliderValue = 1.0f;
}
void Update()
{
pressSpacebar();
}
void pressSpacebar()
{
if (Input.GetKeyDown("space"))
{
filluptheslider();
}
}
void filluptheslider()
{
ProgressSlider.value += sliderValue * Time.deltaTime;
}
There are a few ways to handle this:
Method 1
Boolean value in the class to track the pressed state:
bool pressed = false;
void pressSpacebar()
{
if (Input.GetKeyDown("space"))
{
filluptheslider();
}
if(pressed)
{
filluptheslider();
}
}
Method 2
Coroutine that starts after space is pressed.
void pressSpacebar()
{
if (Input.GetKeyDown("space"))
{
StartCoroutine(FillUpTheSlider);
}
}
IEnumerator FillUpTheSlider()
{
while(ProgressSlider.value < ProgressSlider.maxValue)
{
ProgressSlider.value += sliderValue * Time.deltaTime;
yield return null;
}
}
If you press the space bar multiple times, multiple coroutines will spawn and it will fill faster. You can optionally add the following before you start the coroutine to prevent this behaviour:
StopCoroutine(FillUpTheSlider)
You could alternatively combine method 1 and 2 to remove this behaviour.
bool isFull = false;
bool isPressed = false;
void Update
{
If (Input.GetKeyDown(KeyCode.Space)
&&
!isFull)
{
isPressed = true;
}
if(isPressed)
{
//if you want fill to increase every 0.05 seconds.
StartCoroutine(FillGradually(0.05f));
isPressed = false;
}
}
Ienumerator FillGradually(float fillOffset)
{
//If 100 is your max value
while(ProgressSlider.value < 100)
{
ProgressSlider.value += 1 * Time.deltaTime;
yield return new WaitForSeconds(fillOffset);
}
isFull = true;
}
You can just use a bool condition and when space is pressed, you can just make it true once and when it is true, it will automatically start filling.
bool isSpacePressed; //bydefault, bool class variable is set to false //when initialized
update()
{
if(isSpacePressed==true) //no need to mention ==true just added to make it //readable
{
image.fillAmount=fillvalue+0.1f;
}
}
if(input.GetKey(keyCode.Space)==true)
{
isSpacePressed=true;
}

Scene View Axis of Movement

I have a custom editor and in the scene view I want to be able to execute some code when the UP axis of movement is NOT selected. Is there a way to determine which control is selected before digesting the event in my OnSceneGUI()?
void OnSceneGUI() {
if(/*UP AXIS*/) {
return; // use unity default action
}
// UP Axis not selected do stuff
if (Event.current.isMouse
&& Event.current.button == 0
&& Event.current.type == EventType.MouseDrag)
{
// do some stuff
Event.current.Use(); // digest the event so unity doesn't do default
}
}

Wait function on Unity

I want to wait until "next" button is pressed then continue
child.addChild(tmp);
childrenAdded.Push(tmp);
neighbor.GetComponent.<Renderer>().material.mainTexture = null;
-WAIT UNTIL CLICK ON NEXT BUTTON THEN CONTINUE-
toExpand.Push(tmp);
any idea? I tried:
while(true) {
if(GUI.Button(Rect(500,680 ,100,30),"Next"))
break
}
But it doesn't work; it freezes.
Instead of waiting, you can just have your code called when the button is clicked, like this:
void OnGUI() {
if(GUI.Button(Rect(500,680 ,100,30),"Next"))
toExpand.Push(tmp);
}
}
If possible, consider using Unity 4.6 or later so you can use the new UI which is much easier work with.
You can use Toggle button instead of button so you controll a boolean with toogle and loops what you need in your Update or LateUpdate function like this:
private Rect myRect = new Rect(500,680 ,100,30);
private bool myToggle = false;
void OnGui() {
myToggle = GUI.Toogle(myRect, myToggle, "Next");
}
void Update() {
if(myToggle){
// what I need to create while true;
}
}
Note that is not a good practice to create a new Rect every OnGUI cycle because it runs more than once per frame and it will create a performance issue.
Reading your code again may I could've misinterpreted your needing so if you could clarify what you really what your code to do would be easier to help.
Also, if you just need a "wizard" like sequence of actions I suggest you to take a look on delegates and use something like this:
delegate void MyDelegate();
private MyDelegate myDelegate;
private Rect myRect = new Rect(500,680 ,100,30);
void Start () {
myDelegate = FirstFunction;
}
void FirstFunction() {
// will execute until next button is clicked
}
void SecondFunction() {
// will execute after next button is clicked
}
void OnGui() {
if(GUI.Button(myRect, "Next")) {
myDelegate = SecondFunction;
}
}