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
Related
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 () {
}
}
This question already has answers here:
Accessing a variable from another script C# [duplicate]
(3 answers)
Closed 4 years ago.
Do keep in mind that I am not good at Unity.
I have a Game Object with a variable called hp. I have another Game Object with a trigger collider. When the trigger runs, I want it to edit the variable hp but I don't know how to edit variables from another game object.
Please may I have some help.
In Unity, the OnTriggerEnter(Collider other) function is called when a collision is triggered.
In argument of the function, you get a collider named other, which is a reference to the collider script your object collided with. As any script in unity, you can call other.gameObject to retrieve the colliding gameObject. From then, you can use the GetComponent function to find a script on the object.
In your case, lets say you have an object on which you put this script:
public class Player : MonoBehaviour {
public float hp;
}
You need to create another script that handles the collision. Put this on the object that collides with your player
public class Obstacle : MonoBehaviour
{
public float damages;
private void OnTriggerEnter(Collider other)
{
if(!other.gameObject.HasComponent<Player>())
return;
var player = other.gameObject.GetComponent<Player>();
player.hp -= damages;
}
}
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 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 6 years ago.
Improve this question
in my C# lives class I have a class attribute:
public int life = 0;
and in my C# loose class (so, another script), I want to access to my life attribute of my lives class, but i don't succeed, how to do it ?
When I do
var lv = new lives ();
int lv1 = lv.life;
It shows me that Unity does not allow. I MUST use GetComponent
so I do with get component
var lv = gameObject.GetComponent<lives> ();
int lv1 = lv.life;
And I have a null pointer exception, so it is not understandable ?
You don't use new to create a reference to MonoBehaviour derived classes.
The GetComponent call needs to be associated to the gameobject that class is actually on like this:
public GameObject objectWithLives; // populate this e.g. via inspector
...
Lives lives = objectWithLives.GetComponent<Lives>(); // NOTE: Always start classes with an uppercase!
Saying
Lives lives = gameObject.GetComponent<Lives>();
only works if that script is on the same object as this script.
You don't need to actually store the variable of that other script into a local variable (at least if they shall refer to the same value, otherwise you can do that). Just say something like
lives.life = 5;
If that class (script) actually is not meant to be on a gameobject then you don't derive from MonoBehaviour (that's not a must, only if you need stuff from MonoBehaviour and/or want to put the script on an object).
If you don't derive from MonoBehaviour then you use the standard way of referencing the class by saying new Lives().
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...