Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am programming the table top game "Get Bit!". First i created a console version and now I'm trying to port it to Unity.
My Problem:
In console the whole game is linear. So PlayCards() asks the Player what card he wants to play and then waits until user enters its value.
In unity I'm trying to get the input via Buttons, but that does not wait for user Input and contues with MoveSwimmer() and so on. I tried to get the value via while(inupt == -1), but that freezes the whole game.
Currently the Run() method is in a class Game : MonoBehaviour attached to camera.
Here's the code of the problematic functions after taking McAden's advice:
void Game::Update ()
{
this.GameRun = true;
Debug.Log(string.Format("Round: {0}", (round - 1)));
Debug.Log("POSITION: " + PlayerPositionString());
while (GameRun)
{
PlayCards();
MoveSwimmers();
GetBit();
EndTurn();
}
Debug.Log(string.Format("Congrats! Player {0} won!", playerPosition.First()));
}
private void Game::PlayCards()
{
for (int i = 0; i < playerScripts.Count; i++)
{
if (playerScripts [i].IsAlive())
cardsPlayed.Add(playerScripts [i].PlaceCard());
}
}
override public Card Player::PlaceCard()
{
// a MonoBehaviour that shows for each card a Button that sets the value member ChoosenCardValue (on default -1).
GUICardChooser chooser = Camera.main.GetComponent<GUICardChooser>();
while (chooser.ChoosenCardValue == -1)
;
int cardIndex = cards.FindIndex(c => c.Value == chooser.ChoosenCardValue);
Card theChoosenOne = cards [cardIndex];
cards.RemoveAt(cardIndex);
return theChoosenOne;
}
Am I focussing on the wrong pattern? How can I fix this issue?
Thanks for help.
In Unity3D you don't need to define your own game loop. Unity already does that for you. Create an Update function.
Inside your Update function - check for input and react to it. Since it's in a loop, use if instead of while. Update is already within a loop though you might end up looking up the differences between it and FixedUpdate.
something like:
void Update
{
if (Input.GetKeyUp (KeyCode.LeftArrow))
{
DoSomething();
}
}
You'll want to research the different ways of dealing with input. You won't always want to use GetKeyUp. You might use GetAxis or GetButtonUp for example.
As #Didier suggests in his answer you'll probably want to end up implementing a State Machine of some sort in the long run.
First I think you should look through Unity docs and Unity samples.
But if you want to implement it one of the possibilities would be to create a state mashine. And inside your Update() method you will behave according to your current state. But it's just one possibility. It all depends on your gameplay...
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I have been coding for many many moons now but I'm very new to unity and C#. Currently, I'm trying create a script to both display a camera feed and when a button is pressed, take a still of that feed so that I can run an OCR algorithm on it. I took most of my code (and consequently the code comments) from here: Can I take a photo in Unity using the device's camera?
The problem I'm having is that I keep getting this error in unity which prevents me from even running the code:
Assets/Scripts/WebCam.cs(22,42): error CS0103: The name 'webCamTexture' does not exist in the current context
Line 22 is in the TakePhoto() function of my code. This seems to be an issue with scope but as far as I can tell, with my very limited grasp of C#, the "webCamTexture" variable is in the class scope. So as such it should be accessible in any of class WebCam's methods. But as I said before I'm still very new to C# and Unity, so maybe I'm just missing something.
It might be worth noting, for those who are just C# people and haven't used Unity before, that the start() function is supposed to run immediately when the app starts. So, in theory, I expect that the "webCamTexture" variable should always have a non-null value by the time the TakePhoto() function gets executed.
Any help would be greatly appreciated. Here's there code in question:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
public class WebCamScript : MonoBehaviour
{
public RawImage rawimage;
private WebCamTexture webcamTexture;
private void Start()
{
Debug.Log("Hello World!: WebCamScript Start()");
if (webcamTexture == null)
{
webcamTexture = new WebCamTexture();
}
rawimage.material.mainTexture = webcamTexture;
if (!webcamTexture.isPlaying)
{
webcamTexture.Play();
}
}
public IEnumerator TakePhoto() // Start this Coroutine on some button click
{
// NOTE - you almost certainly have to do this here:
yield return new WaitForEndOfFrame();
// it's a rare case where the Unity doco is pretty clear,
// http://docs.unity3d.com/ScriptReference/WaitForEndOfFrame.html
// be sure to scroll down to the SECOND long example on that doco page
Texture2D photo = new Texture2D(webcamTexture.width, webcamTexture.height);
photo.SetPixels(webcamTexture.GetPixels());
photo.Apply();
// //Encode to a PNG
// byte[] bytes = photo.EncodeToPNG();
// //Write out the PNG. Of course you have to substitute your_path for something sensible
// File.WriteAllBytes(your_path + "photo.png", bytes);
}
}
UPDATE: Was a typo. Looks like all I needed was a fresh pair of eyes. Thanks all. That being said I'm still having some issues that are making me scratch my head. I'm still not seeing my "takePhoto" function when I go to link it to my button. Any ideas why? I updated my code above to reflect it's current state. See photo:
missing script in drop down
If this is your exact code, you defined a webcamTexture variable but you are trying to use webCamTexture : watch out for upper/lowercase, keep your naming consistent :)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
enter image description hereSo I have started to make a game (With very limited knowledge) using Unity.
Its a 2D game. I have created a script which is for health, food .. ETC..
As soon as I try to load this into unity It comes up with the following error?
'Can't add script component 'Game Manag' because the script class cannot be found. Make sure that there are no compile errors and that the file name and class name match.'
Any Ideas?
https://i.imgur.com/mhEodFW.jpg
Alright looks like you have quite a few errors in your code. You must post your code here, do not post a screenshot. Firstly I would say create a new script with name GameManager. Make sure there are no spaces between Game and Manager. Secondly, your Debug.Log is throwing errors as well.
I have corrected those errors and posted your error-free code below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
int Health;
int Day;
int Food;
int Money;
// Use this for initialization
void Start () {
Health = 100;
Food = 100;
Day = 0;
Money = 0;
Debug.Log(Health);
}
// Update is called once per frame
void Update () {
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I make a game in C# under Unity and I have a problem with the code for attack.
I've already tried to put this code in a void in the enemy script.
Enemy code :
public int Life = 5;
public int Speed = 100;
Player attack code :
// Use for player attack
public void Attack () {
if (Input.GetKeyDown("space")) {
EnemyD.Life = EnemyD.Life - 1;
}
}
// Use for Auto Attack
public void AutoAttack () {
EnemyD.Life = EnemyD.Life - 1;
}
Unity return this error :
error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement.
Thank you for your help, Jason.
If all enemies or group of enemies will have the same script, then you could call a particular script by grabbing whichever enemy was hit.
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Monster"))
{
collision.gameObject.GetComponent<EnemyD>().Life -= 1;
}
}
So if you have two enemies and you've attacked the first one, only on him will be applied this action.
Try to put scripts with proper Class name, I guess your enemy script is named EnemyD.
Let's come to point - your player is trying to access member without an instance, so it is a error.
If you try to access them without instance you have to put static before members , which means Of the class , Not of an instance.
Normally there is so many enemy, we don't use static, instead use the approach of Nikola G. from here [Posted as answer in this question].
Some links you might find helpful :
Static Variable
Class Variable
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm getting some issues with logic and the behavior that is happening in my game.
I want to implement a powerup and this powerup just stops that character for certain of time. So to do it I'm simply disabling his script so he does nothing. Now this is working but the problem is I can't find a way to enable the script back to him after 5 seconds. I want to stop the character for 2 seconds.
Your code is wrong. You should be using Invoke.
It is extremely simple.
Something like ...
void ApplyPenalty()
{
yourPauseSystem = true;
Debug.Log("starting penalty..");
Invoke("EndPenalty", 5f);
}
void EndPenalty()
{
yourPauseSystem = false;
Debug.Log(" ...ended penalty");
}
Don't forget the Debug.Log statements.
Note that ideally ApplyPenalty (and EndPenalty) should be
ACTUALLY ON THOSE GAME OBJECTS.
actually put that code ON THOSE game objects, NOT here in the "collision object code". You get it?
So in your case, to apply the penalty, it will be something like ..
void OnCollisionEnter(Collision c)
{
if ( (c.gameObject.tag == "Character") )
c.GetComponent<YourHerosCode?().ApplyPenalty()
}
you see?
You MUST use the physics layers system. You literally have to use it to make collisions in Unity. you MUST use the "physics grid"...
to indicate what can collide with what. In your comment you say they "won't collide" but you can absolutely make anything collide (or not collide) with anything.
Note that in practice EVERYTHING needs its own physics layer, in Unity.
Certainly your hero, enemy etc will all have their own layer.
Tip: certainly "enemy projectiles" and "player projectiles" need their own separate layer, both.
If NullReference is on this line gameObject.GetComponent<PlayerControls>().enabled = true; is probably because you try to reference to a disable component.
Try to assign a var in Start() to the component
var playerController = gameObject.GetComponent<PlayerControls>();
and then use this to refer to it and enable/disable it:
playerController.enable = true; //or false
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have an application that have several methods which checks for various errors on a computer. Right now i am calling the methods on load event of the form, but i kinda want to display what the program is doing by updating a label text for everything it does, like a progressbar. It should go from method to method in order.
And later i also want to check if everything has runned successfully. Should i look into Threading Tasks for this? Like starting a task for each method, stopping the task if it fails?
I would suggest to create the following classes:
WorkstationCheckBase - should be the base class for all checks.
WorkstationCheckRunner - gets a list of all checks and summarize
the result of each WorkstationCheckBase.
With that, you will encapsulate the checking from your UI and separete these concepts.
Now for you second question to show up on the UI some information (my assumation is that you use WinForm). For that you need a background task and update the UI frequently. You could use the Backgroundworker class for that.
Short answer: No, don't use threading-
Long answer: It depends!
When you get yourself into threading you start to face loads of other concurrency related problems, if all you want is to show a label of what is happening I would not suggest to use threads.
Since I have no code to look at I can only give you suggestions for how to solve your problem (without threading). The simplest way would be:
public void CheckErrors()
{
string errorText = string.Empty;
if (ErrorOneHasOccured(out errorText))
{
ErrorLabel += errorText;
}
errorText = string.Empty;
if (ErrorTwoHasOccured(out errorText))
{
ErrorLabel += errorText;
}
}
private bool ErrorOneHasOccured(out string errorText)
{
bool errorHasOccured = false;
errorText = string.Empty;
// DO error checking somehting
if (errorHasOccured)
{
errorText = "An error description";
return true;
}
return false;
}
Where :
ErrorLabel is the string property for the error text you want to display.
ErrorOneHasOccured is an example method for error checking, using the "Try" pattern.
I think this is the simplest way you can do it, but you can obviously engineer it further depending on what and why you need it.