I am making an app for a school project, and am working with showing/hiding images to make an 'upgrade' and 'downgrade' button. I have made it so when you press a button, it updates the image. At first I had this with structuring my code differently. The issue with that was the fact it wouldnt load my current picture state in again after I left and re-entered the scene (although it would save the value of the upgradelevel). When I tried to restructure it, nothing works. What am I doing wrong here (if it can even be done like this...)?
I had structured the code differently at first, but came to the issue of my image not loading when I re-entered the scene. Structuring the code like this I felt it would bypass that issue. Now another issue has come up.
public GameObject woodWeapon;
public GameObject stoneWeapon;
public GameObject metalWeapon;
public static int weaponLevel = 0;
public void upgradeWeapon()
{
weaponLevel += 1;
if (weaponLevel > 3)
{
weaponLevel = 3;
}
}
public void downgradeWeapon()
{
weaponLevel -= 1;
if (weaponLevel < 0)
{
weaponLevel = 0;
}
}
public void Update()
{
if (weaponLevel == 0)
{
woodWeapon.SetActive(false);
stoneWeapon.SetActive(false);
metalWeapon.SetActive(false);
}
else if (weaponLevel == 1)
{
woodWeapon.SetActive(true);
stoneWeapon.SetActive(false);
metalWeapon.SetActive(false);
}
else if (weaponLevel == 2)
{
woodWeapon.SetActive(false);
stoneWeapon.SetActive(true);
metalWeapon.SetActive(false);
}
else if (weaponLevel == 3)
{
woodWeapon.SetActive(false);
stoneWeapon.SetActive(false);
metalWeapon.SetActive(true);
}
}
Expected result: Pressing 'upgrade' button updates my screen with am image, a wood sword instead of nothing, a stone sword instead of a wood sword, etc...
pressing 'downgrade' should do the same thing, but the other way around
Reality: Pressing either 'upgrade' or 'downgrade' does nothing to the image.
Related
if (Input.GetMouseButtonDown(0))
{
if (currentanim >= 3)
{
currentanim = 1;
}
if (swordanimactive == false)
{
if (swordblockanimactive == 1)
{
currentanim = currentanim + 1;
//the problem seems to be here
Swordcontroller.speed = attackspeed;
Swordcontroller.SetInteger("attackindex", currentanim);
Swordcontroller.SetTrigger("attack");
}
}
}
The problem is when I set the attack speed over 1 (regular speed), after a few clicks it just stops working. I have no idea what causes this and I don't know how to fix it since I just implemnted this new animation system. Also, the current animation is just because there are 3 sword animations. However, if I set it to only one animation it works perfectly fine. When I use 3 different animations it doesn't work.
First of all, I do not really know how you set up the animator, but I recommend this structure.
Multi Animation Animator
Has Exit Time
Maybe you can create some dataType like
public class MeleeAttackInstance
{
public string animationName;
public float animationSpeed;
public float modifiedSpeed;
public void ApplySpeedModifier(int queCount)
{
animationSpeed*(queCount +1);
}
}
And make a queue of this attacks. When craracter should attack, you place item in queue and get the top one applying modified speed.
I have a Unity script in c# where a public list of sprites is declared and then populated manually in the inspector.
The list consists of 19 sprites of cars.
These cars are available only if the player completed each level.
For example: When you open the game for the first time, you only have 1 available car but if you complete level 1, you unlock another car, when you complete level 2, you get another and so on.
My question is, being that I manually populated the list, how do I go about re-adding the same sprite back when a level is completed?
I was going to use cars.RemoveRange(1, 18) to remove them from the list but do not know a way to add them back without calling every sprite back manually. I believe there is a simpler, better way that I do not know about.
This is the script:
public class CarSelection : MonoBehaviour
{
public List<Sprite> cars; //store all your images in here at design time
public Image displayImage; //The current image thats visible
public Button nextCar; //Button to view next image
public Button previousCar; //Button to view previous image
private int i = 0; //Will control where in the array you are
void OnEnable()
{
//Register Button Events
nextCar.onClick.AddListener(() => NextCarButton());
previousCar.onClick.AddListener(() => PreviousCarButton());
}
private void Start()
{
cars.RemoveRange(1, 18);
if (FinishLineTouch.levelOneComplete == true) {
//Re-adding the same sprites here
}
}
public void NextCarButton()
{
if (i + 1 < cars.Count)
{
i++;
}
}
public void PreviousCarButton()
{
if (i - 1 >= 0)
{
i--;
}
}
void Update()
{
if (LevelSelect.isCarChosen == true) {
nextCar.interactable = false;
previousCar.interactable = false;
}
displayImage.sprite = cars[i];
}
}
Thanks in advance.
You have a small flaw in your logic here.
Saying that you add the car sprites in the inspector, removing all the sprites is not ideal.
You can have a list of all the sprites, and a list with available options (starts with sprite[0] and adds each time you complete the level).
However, if you want to know how to add them back after deleting them, you need to make a copy in a global variable, so it's more efficient to try what I am suggesting above.
You should have two different arrays, one for the sprites, and the other one for if the player unlocked it yet. Or you should create a custom class that has the sprite of the car, and if it is unlocked yet.
Sounds like all you really need to do is make sure the index doesn't exceed the unlocked cars
if(i + 1 < cars.Count && i + 1 <= amountOfFinishedLevels)
{
i++;
// and then you really should do this in both methods and not every frame
displayImage.sprite = cars[i];
}
and don't remove/readd any items at all.
I have implemented the dialog system from this Brackeys video in my project. Everything works perfectly, but when I have done the build for android I have seen that printing long texts slows the game down.
The code divides the sentence to be displayed in the UI into an array of characters and then prints each character one by one, with a small delay. I have been doing several tests and first I thought that the problem was the coroutine from where the characters were printed. But then I have removed the code from the coroutine and I have seen that the more characters it prints, the more the game slows down.
void FixedUpdate()
{
if(typeSentence)
{
if(t <= 0)
{
TypeChar();
t = charDelay;
}
t -= Time.fixedDeltaTime;
}
}
private void TypeChar()
{
GUIs[dialogue.UIIndex].dialogueText.text += charSentence[sentenceIndex];
sentenceIndex++;
if (sentenceIndex >= charSentence.Length)
{
typeSentence = false;
sentenceIndex = 0;
GUIs[dialogue.UIIndex].continueButton.SetActive(true);
}
}
I don't know if there is a more efficient way to do it, or if someone can explain to me what is happening and why it slows down so much.
Instead of triggering TypeChar() method in fixed update, you can convert TypeChar() to a Coroutine that can handle time more performing way.
private IEnumerator TypeChar()
{
while(sentenceIndex >= charSentence.Length)
{
if(typeSentence)
{
GUIs[dialogue.UIIndex].dialogueText.text += charSentence[sentenceIndex];
sentenceIndex++;
yield return new WaitForSeconds(charDelay);
}
}
typeSentence = false;
sentenceIndex = 0;
GUIs[dialogue.UIIndex].continueButton.SetActive(true);
}
And you can delete typeSentence variable completely if you do not change it out of scope.
And you can call it at Start instead of FixedUpdate.
private void Start()
{
StartCoroutine(nameof(TypeChar));
}
I have an animatormanager able to create run time animation from 1 animation (start frame, end frame and delay then the speed is calculated, will do morphing and more later). My unity version is 5.3.1f1
Everything work fine, some stuff are not done but are optional. The animator can queue requested animation to prevent interupting the current one.
The thing is, I can only start 1 time an animation with an object. The code to launch the next animation is exactly the same but there is just nothing to do.
Event if its 2 time the same animation with the same animation data
All formula are good and tested.
I did intensive debugging with breakpoint to make sure everything is fine at any point
Is there something to prevent me from starting an animation 2 time on an object one after an other?. I have no error or warning at all. The first animation work fine no matter the settings I put in my AnimData struct, but the second time, nothing happen.
Here is the essential:
public int? startAnim(int index)
{
if(index < animIndex.Count)
{
startAnim(animIndex[index]);
}
return null;
}
//private because the struct is internal, this make sure the animator keep control of the list.
private int? startAnim(AnimData animD)
{
if(locked)
{
#if UNITY_EDITOR
Debug.Log("anim locked");
#endif
return null;
}
//current anim (queue anim) not finished
if(endTime > Time.time)
{
if(canQueue)
{
addToQueue(animD);
return animDataQ.Count;
}
else
{
return null;
}
}
else
{
endTime = Time.time + animD.TotalTime;
StartCoroutine(animManager(animD));
return 0;
}
return null;
}
#endregion anim starters
private IEnumerator animManager(AnimData animData)
{
animator.speed = Mathf.Abs(animData.calculateSpeed(animLength, AnimType.main, currentKey).Value);
//animator.Play(0,0, animData.StartKey/animLength);
if(animData.AnimSpeed > 0)
{
animator.Play(0,0, animData.StartKey/animLength/2);
}
else
{
//animator.Play(0,0, (animLength * 2) - (animData.StartKey/animLength));
animator.Play(0,0, (((animLength*2) - animData.StartKey)/(animLength * 2)));
}
//animator.Play(0,0, (animData.AnimSpeed > 0) ? animData.StartKey/animLength : ((animLength * 2) - (animData.StartKey/animLength)));
yield return new WaitForSeconds(animData.Delay);
animator.Stop();
yield return null;
endAnim();
}
private void addToQueue(AnimData animD)
{
animDataQ.Enqueue(animD);
endTime += animD.TotalTime;
queueTime += animD.TotalTime;
}
private void endAnim()
{
if(canQueue && animDataQ.Count > 0)
{
StartCoroutine(animManager(animDataQ.Dequeue()));
}
}
Thanks for your time.
i found a work around.
I dont want to mark it as an accepted solution since its not "clean" in my opinion
there is certainly some kind of problem with the animator for some specific case like mine.
my solution was to use animator.speed = 0 instead of animator.stop();
everything worked instantly with that small change
i will ask my question to the unity forum because there is something strange for sure
I recently started to make video games using the XNA game studio 4.0. I have made a main menu with 4 sprite fonts using a button list. They change color from White to Yellow when I press the up and down arrows.
My problem is that when I scroll through it goes from the top font to the bottom font really fast and goes straight to the last one. I am unsure why this is? Is it because I am putting it in the update method and it is calling it every 60 seconds or so?
Here is my code for when I press the arrow keys.
public void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (CheckKeyboard(Keys.Up))
{
if (selected > 0)
{
selected--;
}
}
if (CheckKeyboard(Keys.Down))
{
if (selected < buttonList.Count - 1)
{
selected++;
}
}
keyboard = prevKeyboard;
}
public bool CheckKeyboard(Keys key)
{
return (keyboard.IsKeyDown(key) && prevKeyboard.IsKeyUp(key));
}
I need someone to help me slow it down to a reasonable speed.
If you could help me it would be greatly appreciated.
I think the issue is because you are not setting prevKeyboard correctly.
Try this:
public void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (CheckKeyboard(Keys.Up))
{
if (selected > 0)
{
selected--;
}
}
if (CheckKeyboard(Keys.Down))
{
if (selected < buttonList.Count - 1)
{
selected++;
}
}
prevKeyboard = keyboard; // <=========== CHANGE MADE HERE
}
public bool CheckKeyboard(Keys key)
{
return (keyboard.IsKeyDown(key) && prevKeyboard.IsKeyUp(key));
}
I think its because
if (CheckKeyboard(Keys.Up))
{
if (selected > 0)
{
selected--;
// This loops executes so quick before you release button.
// Make changes here to stop the loop if the button is pressed and loop
// executed once.(May be) just **return;** would do ?
}
}
if (CheckKeyboard(Keys.Down))
{
if (selected < buttonList.Count - 1)
{
selected++;
// This loops executes so quick before you release button.
// Make changes here to stop the loop if the button is pressed and loop
// executed once.(May be) just **return;** would do ?
}
}