When i try to print the variable from another class, it prints the undeclared variable, so only 0.
Here is an example:
public class Player
{
Enemy enemy;
public void Initialize(){
enemy = new Enemy();
}
public void Update()
{
Console.WriteLine(enemy.Rectangle);
}
}
public class Enemy()
{
public Rectangle Rectangle;
public void Update()
{
Rectangle = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);
}
}
I think the following code can help you
public class Player
{
Enemy enemy;
public void Initialize()
{
enemy = new Enemy();
}
public void Update()
{
enemy.Update();
Console.WriteLine(enemy.Rectangle);
}
}
public class Enemy
{
public System.Drawing.Rectangle Rectangle;
public void Update()
{
Rectangle = new System.Drawing.Rectangle(5, 10, 10, 10);
}
}
Main:
Player p = new Player();
p.Initialize();
p.Update();
Result:
Related
I've attached my code, tried a few different things here and there but to no avail. If someone can help out and explain why your code works that would be amazing, thank you.
I have NPCTextPerson as a component and this is the script, it shows above the object but if they move it will not update the text location.
I am looking to update the script to display the text as is, but to update and follow the object until the text disappears.
This is the "NPCTextPerson" component script attached to the game object.
public class NPCTextPerson : Collidable
{
public string message;
public float cooldown = 4.0f;
private float lastShout;
protected override void Start()
{
base.Start();
lastShout = -cooldown;
}
protected override void OnCollide(Collider2D coll)
{
if (Time.time - lastShout > cooldown)
{
lastShout = Time.time;
GameManager.instance.ShowText(message, 25, Color.white, transform.position + new Vector3(0,0.16f,0), Vector3.zero, cooldown);
}
}
}
Here is the "Game Manager" script handling the floating text module
public class GameManager : MonoBehaviour
{
public static GameManager instance;
private void Awake()
{
if(GameManager.instance != null)
{
Destroy(gameObject);
Destroy(player.gameObject);
Destroy(floatingTextManager.gameObject);
Destroy(hud);
Destroy(menu);
return;
}
//PlayerPrefs.DeleteAll();
instance = this;
SceneManager.sceneLoaded += LoadState;
SceneManager.sceneLoaded += OnSceneLoaded;
}
// Resoures for the game
public List<Sprite> playerSprites;
public List<Sprite> weaponSprite;
public List<int> weaponPrices;
public List<int> xpTable;
// References
public Player player;
public Weapon weapon;
public FloatingTextManager floatingTextManager;
public RectTransform hitpointBar;
public Animator deathMenuAnim;
public GameObject hud;
public GameObject menu;
// Logic
public int pesos;
public int experience;
// Floating Text
public void ShowText(string msg, int fontSize, Color color, Vector3 position, Vector3 motion, float duration)
{
floatingTextManager.Show(msg, fontSize, color, position, motion, duration);
}
This is the "Floating Text" script handling all the show/update/get
public class FloatingTextManager : MonoBehaviour
{
public GameObject textContainer;
public GameObject textPrefab;
private List<FloatingText> floatingTexts = new List<FloatingText>();
private void Update()
{
foreach (FloatingText txt in floatingTexts)
txt.UpdateFloatingText();
}
public void Show(string msg, int fontSize, Color color, Vector3 position, Vector3 motion, float duration)
{
FloatingText floatingText = GetFloatingText();
floatingText.txt.text = msg;
floatingText.txt.fontSize = fontSize;
floatingText.txt.color = color;
floatingText.go.transform.position = Camera.main.WorldToScreenPoint(position); // Transer world space to screen space so we can use it in the UI
floatingText.motion = motion;
floatingText.duration = duration;
floatingText.Show();
}
private FloatingText GetFloatingText()
{
FloatingText txt = floatingTexts.Find(t => !t.active);
if(txt == null)
{
txt = new FloatingText();
txt.go = Instantiate(textPrefab);
txt.go.transform.SetParent(textContainer.transform);
txt.txt = txt.go.GetComponent<Text>();
floatingTexts.Add(txt);
}
return txt;
}
}
I am trying to make a vehicle changing game where there are 3 gameObject: car, tank and hover and if I press a button to change from car to a tank/hover i want them to be in a position where the car was.
the z axis is forward
I tried this code below but when I go backwards this will not work
UnityEngine;
public class Carswitcer : MonoBehaviour
{
public Transform car;
public Transform hover;
public Transform tank;
void Start()
{
car.gameObject.SetActive(true);
tank.gameObject.SetActive(false);
hover.gameObject.SetActive(false);
}
public void Car()
{
if (car.position.z < hover.position.z)
{
car.position = hover.position;
}
if (car.position.z < tank.position.z)
{
car.position = tank.position;
}
car.gameObject.SetActive(true);
tank.gameObject.SetActive(false);
hover.gameObject.SetActive(false);
}
public void Tank()
{
if (tank.position.z < hover.position.z)
{
tank.position = hover.position;
}
if (tank.position.z < car.position.z)
{
tank.position = car.position;
}
car.gameObject.SetActive(false);
tank.gameObject.SetActive(true);
hover.gameObject.SetActive(false);
}
public void Hover()
{
if (hover.position.z < car.position.z)
{
hover.position = car.position;
}
if (hover.position.z < tank.position.z)
{
hover.position = tank.position;
}
car.gameObject.SetActive(false);
tank.gameObject.SetActive(false);
hover.gameObject.SetActive(true);
}
Why compare the z at all? Simply always copy the position of the currently active vehicle:
public class Carswitcer : MonoBehaviour
{
public Transform car;
public Transform hover;
public Transform tank;
// Store the current vehicle
private Transform currentVehicle;
void Start()
{
tank.gameObject.SetActive(false);
hover.gameObject.SetActive(false);
SetActiveVehicle(car);
}
private void SetActiveVehicle(Transform newActiveVehicle)
{
// Is there a current vehicle?
if(currentVehicle)
{
// If so copy its position and set it inactive
newActiveVehicle.position = currentVehicle.position;
currentVehicle.gameObject.SetActive(false);
}
// Store the new active reference and set it active
currentVehicle = newActiveVehicle;
currentVehicle.gameObject.SetActive(true);
}
public void Car()
{
SetActiveVehicle(car);
}
public void Tank()
{
SetActiveVehicle(tank);
}
public void Hover()
{
SetActiveVehicle(hover);
}
I'm using XNA to create a Space Invaders copy. So I'm animating many sprites with the same logic placed in their own class, but using different values for most vars. Here is my way of animating from spritesheets:
Texture2D playerTex;
Vector2 playerPos = new Vector2(x, y), playerOrigin;
Rectangle playerHitBox;
float animationTimer = 0f, animationInterval = 100f;
int currentFrame = 1, frameWidth = example number, frameHeight = example number 2;
public void LoadContent(ContentManager Content)
{
playerTex = Content.Load<Texture2D>("ship");
}
public void Update(GameTime gameTime)
{
playerHitBox = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
playerOrigin = new Vector2(playerHitBox.X / 2, playerHitBox.Y / 2);
animationTimer += (float)gameTime.ElapsedGameTime.Milliseconds;
if (animationTimer > animationInterval)
{
currentFrame++;
animationTimer = 0f;
}
if (currentFrame == 2)
{
currentFrame = 0;
}
playerHitBox = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
playerOrigin = new Vector2(playerHitBox.Width / 2, playerHitBox.Height / 2);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(playerTex, playerPos, playerHitBox, Color.White, 0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
}
Instead of using this logic for every animating object within its own class I'm looking for a way to create a sprite class anduse inheritance to Update()/Draw() the sprite. Could something like this be a good approach for the Draw() method?
public void Draw(Texture2D spriteTex, Vector2 spritePos, Nullable<Rectangle> spriteSourceRect, Color spriteColor, Single spriteRotation, Vector2 spriteOrigin, Vector2 spriteScale, SpriteEffects spriteEffects, Single spriteLayerDepth, SpriteBatch spriteBatch)
{
if (spriteTex != null)
{
spriteBatch.Draw(spriteTex, spritePos, spriteSourceRect, spriteColor, spriteRotation, spriteOrigin, spriteScale, spriteEffects, spriteLayerDepth);
}
}
You can:
Create Sprite class to keep common animation properties like texture, duration and current index.
Create Invider class for custom data like position, health and other.
Create a collection to store custom data for each object in game class.
For example:
class Sprite
{
public Texture2D texture;
public Rectangle Frame;
private frameIndex;
private frameCount;
private frameDuration;
private frameInterval;
public Sprite(Texture pTexture, ...)
{
// init sprite data
}
public Update(GameTime pGameTime)
{
// update sprite data
}
}
class Invider
{
private Sprite Sprite;
public Vector2 Porision;
public int Health;
public Invider(Sprite pSprite, Vector2 pPosition)
{
this.Sprite = pSprite;
this.Position = pPosition;
}
public void Update(GameTime pGameTime)
{
// update invider data
}
public void Draw(SpriteBatch pSpriteBatch)
{
pSpriteBatch.Draw(this.Sprite.Texture, this.Sprite.Frame, this.Position, Color.White);
}
}
public class Game1 : Game
{
private SpriteBatch spriteBatch;
private Dictionary<int, Invider> invidersByID;
private Sprite inviderSprite;
public override Initialize()
{
// fill inviderByID collection
}
public override LoadData()
{
// create inviderSprite
}
public static UpdateStatic(GameTime pGameTime)
{
// update static data like frame index
}
public override void Update(GameTime pGameTime)
{
this.inviderSprite.Update(pGameTime);
foreach(Invider invider in invidersByID.Values){
{
invider.Update(pGameTime);
}
}
public override Draw(SpriteBatch pSpriteBatch)
{
this.spriteBatch.Begin();
foreach(Invider invider in invidersByID.Values){
{
invider.Update(pGameTime);
}
this.spriteBatch.End();
}
}
I am trying to call a 'shoot laser' function, which is in my ProjectileManager Class, from my Player class controls.
Thing is, when I call the exact same function from either my ProjectileManager or the Game1 (main game) class - it works. otherwise I am getting a null on the sprite.
I am doing a content.load on the sprite in projectilemanager class, which works fine when i call the shoot laser function from either the projectilemanager itself or the main game - but not the player class?
note: ive cut out alot of pointless additional functions within these classes for readability
Game1 Class
public class Game1 : Microsoft.Xna.Framework.Game
{
// CLASSES
Player myPlayer;
ProjectileManager projectileManager = new ProjectileManager();
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
projectileManager.ContentLoad(Content);
}
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.V)) //SHOOT LASER TEST - WORKS
{
projectileManager.ShootLaser(new Vector2(5, 5), 5, 1, new Vector2(0, 0), 0, 0);
}
myPlayer.Update();
projectileManager.Update();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
GraphicsDevice.SamplerStates[0] = noFilter;
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null);
myPlayer.Draw(spriteBatch);
projectileManager.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Player Class
class Player
{
// Inherent classes
ProjectileManager projectileManager = new ProjectileManager();
Texture2D sprite;
public Vector2 direction;
float speed;
float health;
int spriteType;
public void Update()
{
UpdateControls();
}
void UpdateControls()
{
if (Keyboard.GetState().IsKeyDown(Keys.Space)) //SHOOT LASER - DOESNT WORK
{
projectileManager.ShootLaser(new Vector2(5, 5), 5, 1, new Vector2(0, 0), 0, 0);
}
}
}
Projectile Manager Class
class ProjectileManager
{
//Lists
List<Projectile> projectiles = new List<Projectile>();
//Sprites
Texture2D sprite;
Texture2D spriteLaser;
//Attributes
Vector2 position;
Vector2 dimensions;
int attackPower;
int moveType; //0 = direction based, 1 = homing on player, 3 = hybrid of both (like a missile that fires straight then turns towards target
int team; //the team that the laser is on for collision
Vector2 direction;
float speed;
public ProjectileManager(){}
public void Update()
{
if (Keyboard.GetState().IsKeyDown(Keys.E))
{
ShootLaser(new Vector2(5,5), 5, 1, new Vector2(0,0), 0, 0);
}
foreach (Projectile each in projectiles)
{
each.Update();
}
}
public void ContentLoad(ContentManager content)
{
spriteLaser = content.Load<Texture2D>("playerLaser");
}
public void Draw(SpriteBatch spritebatch)
{
foreach (Projectile each in projectiles)
{
each.Draw(spritebatch);
}
}
public void ShootLaser (Vector2 a_position, int a_attackPower, float a_speed, Vector2 a_direction, int a_moveType, int a_team)
{
position = a_position;
attackPower = a_attackPower;
speed = a_speed;
direction = a_direction;
moveType = a_moveType;
team = a_team;
projectiles.Add(new Projectile(spriteLaser, position, 5, 2, new Vector2(0,1), 0, 0));
}
}
projectile class
class Projectile
{
Vector2 position;
int attackPower;
int moveType; //0 = direction based, 1 = homing on player, 3 = hybrid of both (like a missile that fires straight then turns towards target
int team; //the team that the laser is on for collision
Texture2D sprite;
Vector2 direction;
float speed;
public Projectile(Texture2D a_sprite, Vector2 a_position, int a_attackPower, float a_speed, Vector2 a_direction, int a_moveType, int a_team) //possibly add another variable for hitting other projetiles / cancelling them out
{
sprite = a_sprite;
position = a_position;
attackPower = a_attackPower;
speed = a_speed;
direction = a_direction;
moveType = a_moveType;
team = a_team;
}
public void Update()
{
//movement
// if movetype = 1
if (moveType == 0) // straight line
{
position.Y++;
//position += direction * speed;
}
}
//public Rectangle GetRectangle()
//{
// return new Rectangle((int)m_position.X, (int)m_position.Y, (int)m_dimensions.X, (int)m_dimensions.Y);
//}
// We pass-in a 'SpriteBatch' object so this function
// can call the 'Draw' function on it.
public void Draw(SpriteBatch spritebatch)
{
spritebatch.Draw(sprite, position, Color.White);
}
}
Ive just started learning C#, I cant find any reference to why in the game and projectile manager classes the shootlaser function works, but calling from the player yields no results.
ive tried to debug using breakpoints and from what I can gather the projectile Texture2D sprite is returning a null when the function is called through the player class..
Thoughts?
Thanks
Add a ContentLoad method to your Player class and call the projectileManager.ContentLoad there then call myPlayer.ContentLoad in Game1.LoadContent Method
public class Game1 : Microsoft.Xna.Framework.Game
{
// CLASSES
Player myPlayer;
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
myPlayer.ContentLoad(CoolContent);
}
player class:
class Player
{
// Inherent classes
ProjectileManager projectileManager = new ProjectileManager();
Texture2D sprite;
public Vector2 direction;
float speed;
float health;
int spriteType;
public void LoadContent(CoolContentType coolContent)
{
projectileManager.LoadContent(coolContent);
}
public void Update()
{
UpdateControls();
}
in addition to linking your ContentLoad Method calls. you should get rid of the Texture2D in the Projectile class because it is redundant.
all you need is the values from the Projectiles in your Draw calls while ProjectileManager stores the texture.
class ProjectileManager
{
//Lists
List<Projectile> projectiles = new List<Projectile>();
//Sprites
Texture2D sprite;
Texture2D spriteLaser;
//Attributes
Vector2 position;
Vector2 dimensions;
int attackPower;
int moveType; //0 = direction based, 1 = homing on player, 3 = hybrid of both (like a missile that fires straight then turns towards target
int team; //the team that the laser is on for collision
Vector2 direction;
float speed;
public ProjectileManager(){}
public void Update()
{
if (Keyboard.GetState().IsKeyDown(Keys.E))
{
ShootLaser(new Vector2(5,5), 5, 1, new Vector2(0,0), 0, 0);
}
foreach (Projectile each in projectiles)
{
each.Update();
}
}
public void ContentLoad(ContentManager content)
{
spriteLaser = content.Load<Texture2D>("playerLaser");
}
public void Draw(SpriteBatch spritebatch)
{
spritebatch.Begin();
foreach (Projectile p in projectiles)
{
spritebatch.draw(spriteLaser, p.position,Color.CoolColor);//see how I use the projectile info (p.position). it doesn't need it's own texture :)
}
spritebatch.End();
}
I have 3 classes:
- Game1 (main class)
- Entity (base entity class)
- Player (player class, extends Entity class)
I draw the player class, but after that I can't seem to change the position of the player object.
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Create a list with all the entities
List<Entity> entityList = new List<Entity>();
//Player
Player player;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
//Create player
Texture2D playertexture = Content.Load<Texture2D>("player/player");
Rectangle playerrectangle = new Rectangle(10, 10, playertexture.Width, playertexture.Height);
player = new Player(playertexture, playerrectangle);
entityList.Add(player);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
//Update players and entities
player.Update(graphics.GraphicsDevice);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//Draw player
player.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
class Entity
{
//Standard variables
int health;
int armor;
float speed;
float friction;
//Get graphic and bounding box
Texture2D texture;
Rectangle rectangle;
public Entity(Texture2D newTexture, Rectangle newRectangle){
texture = newTexture;
rectangle = newRectangle;
}
public void Update(GraphicsDevice graphics) {
}
public void Draw(SpriteBatch spriteBatch) {
}
/*
* Modifiers for the variables
*/
public void modifyHealth(int amount) { health = health + amount; }
public void modifyArmor(int amount){ armor = armor + amount; }
public void modifySpeed(float amount) { speed = speed + amount; }
/*
* Getters for variables
*/
public int getHealth() { return health; }
public int getArmor() { return armor; }
public float getSpeed() { return speed; }
public float getFriction() { return friction; }
/*
* Setters for variables
*/
public void setHealth(int amount) { health = amount; }
public void setArmor(int amount) { armor = amount; }
public void setSpeed(float amount) { speed = amount; }
public void setFriction(float amount) { friction = amount; }
/*
* Functions
*/
public void damage(int damage) {
/*
* Calculate health
*
* Armor takes half the damage, if possible
*/
if (damage / 2 >= armor) {
damage = damage / 2;
armor -= damage;
} else if (armor > 0) {
damage -= armor;
armor = 0;
}
health -= damage;
if(health <= 0){
health = 0;
//TODO Death
}
}
}
class Player : Entity
{
//Create player
Entity player;
//Position and velocity
Vector2 position;
Vector2 velocity;
//Texture and rectangle
Texture2D texture;
Rectangle rectangle;
public Player(Texture2D newtexture, Rectangle newrectangle) : base(newtexture, newrectangle) {
texture = newtexture;
rectangle = newrectangle;
//Set basic variables
this.setHealth(100);
this.setArmor(0);
this.setSpeed(10);
this.setFriction(1);
}
public void Update() {
//Movement
if(Keyboard.GetState().IsKeyDown(Keys.Right)){
rectangle.X += 1;
}
rectangle.Y += 4;
}
public void Draw(SpriteBatch spriteBatch) {
spriteBatch.Draw(texture, rectangle, Color.White);
}
}
If there are also general mistakes I make, do point them out, I want to make everything as good as I can now that I'm still learning. Thanks in advance!
Your calling public void Update(GraphicsDevice graphics)
but the movement code is in public void Update()
What I suggest you do is this, use the virtual and override keywords.
In your entity class it should look like this:
public virtual void Update(GraphicsDevice graphics) {
}
And in your player class
public override void Update(GraphicsDevice graphics) {
//ADD MOVEMENT CODE HERE
}