Typedef-equivalent in C#? - c#

I know this exact question has been asked, but the solution posted there doesn't seem to work for me. Here's the code I'm trying:
namespace ConsoleApplication5
{
class Program
{
enum Tile { Empty, White, Black };
using Board = Tile[8,8];
And the error I get:
Invalid token 'using' in class, struct, or interface member declaration
It seems the "using" clause must be moved outside the Program class, but my Tile enum doesn't exist there. So how am I supposed to do this?

It looks like you're trying to use a name to represent a specific way of instantiating a Tile[,] array.
Why not just declare a method that does this?
Tile[,] GetBoard()
{
return new Tile[8, 8];
}
Another option, though I'd consider this a little bit bizarre (not to mention hacky), would be to define a Board type with an implicit operator to convert to Tile[,], as follows:
public class Board
{
private Tile[,] tiles = new Tile[8, 8];
public static implicit operator Tile[,](Board board)
{
return board.tiles;
}
}
This would actually allow you to do this:
Tile[,] board = new Board();

You cannot use using like that.
You can only use for concrete types, not for 'constructors' as you have used.

Unfortunately, you cannot use using to declare a name for an array type. I don’t know why, but the C# specification doesn’t allow it.
However, you can get pretty close by simply declaring Board as a new type containing the array you want, for example:
public class Board
{
public Tile[,] Tiles = new Tile[8,8];
}
Now every time you say new Board(), you automatically get an 8x8 array of tiles.

Related

What is the correct way to copy a component?

This question has been on my mind for a long time because the process of copying it does not seem so difficult. Although Unity can easily copy countless components with instantiate code, why do not I see such a feature in a single component?
public class FreeFly : MonoBehaviour
{
public float wingSpeed = 2f;
public bool canFly = true;
public void CopyComponent()
{
wingSpeed = 10f;
canFly = false;
var _fly = this;
var secondFly = gameObject.AddComponent<FreeFly>();
secondFly = _fly; // The second component did not register the changes.
}
public void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) CopyComponent();
}
}
As you can see, it does not change anything. Interestingly, the Rider IDE also shows it ineffective in code with a yellow underscore.
What is the best solution?
Considering that variable-to-variable copy is a beginner way, I am looking for a solution that can copy any component using the Generic method. Any help is accepted.
public T CopyComponent<T>(T copyFrom)
{
// I want this one..
return copyFrom;
}
secondFly = _fly; tells the computer "from now on, if I say secondFly, I mean the Component (Object) that _fly referenced at time of executing this line." It does not modify the component that was referenced by the variable secondFly, it only changes what secondFly refers to. This is because secondFly is an Object (any type declared as public class ClassName {...}, Component, Rigidbody, etc), not a primitive type (int, float, double, byte, etc.). Variables that are of Object types aren't data themselves, they point to/reference data.
Beginner Way
You can copy the variables of _fly just like this:
secondFly.wingSpeed = _fly.wingSpeed;
secondFly.canFly = _fly.canFly;
Advanced Way
Because of the way Unity's Components work, I don't think there's a simple way to duplicate a Component and attach it to a GameObject, but if you don't want to manually copy the variables of the Component, try adding this function to your code and calling it to duplicate your Component (from https://answers.unity.com/questions/458207/copy-a-component-at-runtime.html)
public static T CopyComponent<T>(T original, GameObject destination) where T : Component
{
var type = original.GetType();
var copy = destination.AddComponent(type);
var fields = type.GetFields();
foreach (var field in fields) field.SetValue(copy, field.GetValue(original));
return copy as T;
}

Using a class within another classes Constructor, C#

so I am slowly reading through the book "The C# players guide, second edition." and I have gotten to a Try it Out! activity involving classes. It tells me to create a Color class with getters and setters for red, blue, green and alpha, which I have done.
It also told me to make a ball class, which will require size, Color (using the color class) and timesThrown variables. I have done that fine and I am now back in the main Program class making instances of the ball class.
Really I am just curious as to what is a better way to go about making this ball because one way looks more efficient, but then I am not sure how to use the getters and setters of the Color class, and the other way looks less efficient but allows me to use all of that. And without being able to use the methods in the class I don't see why i wouldn't just define the colors within the Ball class anyway, unless just for the sake of learning about classes and how to make them, this tutorial has had me do it this way?
So the way I personally did it first, which let me use all the methods in the Color class was like so:
Color red_color = new Color(255, 0, 0);
Ball red_ball = new Ball(5, red_color);
because that lets me do red_color.GetRed(); for example.
The other way is this:
Ball blue_ball = new Ball(4, new Color(0, 0, 255));
However when I do this way, how am I supposed to use the methods defined within the class Color? My first instinct was to use Static as I am not making a instance, but obviously for example, red, isn't always going to be the same value for each ball so that wouldn't work.
So yeah, does the second approach allow to me use the Colors methods at all? Apologies if I worded myself poorly.
In your ball class you can add a property called color like this
Color BallColor {get;private set;}
and in your constructor you should set the ball color you want
Ball blue_ball = new Ball(4, new Color(0, 0, 255));
and the you can use the color methods like this
blue_ball.BallColor.GetRed();
If the only place you'll need to interact with that instance of Color is inside that instance of Ball, do it the second way.
However, if you'll need to interact with that instance of Color someplace else, do it the first way. For example, if you're creating four red Balls in a row, create one red Color instance and pass it to each of them:
var balls = new List<Ball>();
var red = new Color(255, 0, 0);
for (int i = 0; i < 4; ++i) {
balls.Add(new Ball(4, red));
}
Sometimes one is appropriate, sometimes the other. Neither is absolutely "best"; do what works in the specific case you've got in front of you. Sometimes you might create a local variable just to aid readability.
See #ShlomiHaver's answer as well.
My first instinct was to use Static as I am not making a instance
Well you're making an instance. Every time you see a new keyword that's a new instance. You just don't have a reference for it as you passed it directly to the constructor:
new Ball(4, new Color(0, 0, 255));
If you have a public BallColor Color { set; get; } inside the Ball class then Color is accessible through the Ball object like this :
red_ball.BallColor.Something
So, if you just need the Color object to pass it to the constructor of Ball , use the second method. If you need a reference to Color in order to read/write data to/from that object in the code that follows in your program, then use the first approach.
There is no rule here, it is based on the code that follows and the usage. So you need to ask yourself :
Do I need to keep a reference to the Color object outside my Ball object ?
You certainly can do this, but remember that the context of an instantiated object is always the most important thing.
You want to know the color of the ball, right? So add a suitable method to the Ball class.
public class Ball
{
private int Size { get; set; }
private Color BallColor { get; set;}
Ball(int size, Color color)
{
Size = size;
BallColor = color;
}
public Color GetBallColor()
{
return BallColor;
}
}
Then you can use the ball's color like this:
var ball = new Ball(5, new Color(0, 0, 0));
var ballColor = ball.GetBallColor();
var ballColorRedValue = ballColor.GetRed();
Achieving the same thing using properties is absolutely acceptable.

Custom List .Remove

Heyo. First of all, I'm sorry if I'm asking something that's really simple. It's been holding me up for a day or two and I can't find any tutorials that cover what it is I'm trying to do.
I have a set of cubes that have to hold some game objects, along with an int that displays how important that object is and where it will appear in something called the Resolution Order. That bit is all working fine.
The CubeContents class:
public class CubeContents : IComparable<CubeContents>{
public GameObject objectType;
public int resolutionOrder;
public CubeContents (GameObject name, int importance){
objectType = name;
resolutionOrder = importance;
}
public int CompareTo(CubeContents other){
if(other == null)
return 1;
return resolutionOrder - other.resolutionOrder;
}
The method I'm using passes the specific game object to cube and uses this code to add it to the array:
public void newArrival(GameObject incoming){
int importance = discoverImportanceOfObject (incoming);
thisContents.Add (new CubeContents (incoming, importance));
thisContents.Sort ();
}
discoverImportanceOfObject is basically a long list of "else if" statements that returns a number I'm using to order these things. The problem I'm having is when I'm trying to remove this object from the array before I destroy it. This piece of code basically seems totally non responsive, but it compiles and runs just fine. No odd error messages, nothing.
public void leavingObject(GameObject leaving){
int importance = discoverImportanceOfObject (leaving);
thisContents.Remove (new CubeContents (leaving, importance)));
thisContents.TrimExcess ();
}
I'm at a total loss as to why this is. I've tried all sorts of things (IndexOf, then a RemoveAt, nulling out the entire array and then rebuilding it based on colliders...)
This just feels like it'll be a simple fix that I'm completely overlooking, but as I don't have an error message to search, or any other sort of jumping off point, I'm a bit stuck...
This object will not exist...
thisContents.Remove (new CubeContents (leaving, importance)));
Instead, loop through the thisContents collection to find the object matching the 'leaving' and 'importance'. Then remove that object.

C# (Unity 4.3) Cannot implicitly convert type `ShotScript[]' to `ShotScript'

Thanks all! The issue was I was using GetComponents rather than GetComponent, thanks!
I am fairly new to programming and I am trying to make a 2D game in Unity. I have found a tutorial online which is really good, up until a point (Tut can be found here http://pixelnest.io/tutorials/2d-game-unity/shooting-1/). I've come across an error and can't figure out why. The error occurs when I try and use another script inside my current script (if that makes sense to anyone). The two scripts in question have the name ShotScript and HealthScript and they are below
ShotScript:
using UnityEngine;
using System.Collections;
public class ShotScript : MonoBehaviour {
public int damage = 1;
public bool isEnemyShot = false;
void Start () {
Destroy (gameObject, 20);
}
}
HealthScript:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
public int hp = 2;
public bool isEnemy = true;
void OnTriggerEnter2D(Collider2D Collider) {
ShotScript shot = collider.gameObject.GetComponents<ShotScript>();
if (shot != null) {
if (shot.isEnemyShot != isEnemy) {
hp -= shot.damage;
Destroy (shot.gameObject);
if (hp <= 0) {
Destroy(gameObject);
}
}
}
}
}
The error I get is:
"Assets/Scripts/HealthScript.cs(13,36): error CS0029: Cannot implicitly convert type ShotScript[]' toShotScript'"
I'm rather stuck and so if anyone could point me in the right direction, that'll be great =)
P.S I'm new to this asking questions thing, so if you need any extra info, I'll do my best to provide it
Well this is the problem:
ShotScript shot = collider.gameObject.GetComponents<ShotScript>();
It sounds like GetComponents<ShotScript> is returning an array of ShotScript references, i.e. its return type is ShotScript.
Do you want to take the same action for each ShotScript? If so, you probably want to just use a foreach loop... although you probably only want to check for the hp going negative at the end. I would expect you to be able to remove the check for nullity, too, assuming that GetComponents will just return an empty array if there aren't any such components:
ShotScript[] shots = collider.gameObject.GetComponents<ShotScript>();
foreach (ShotScript shot in shots)
{
if (shot.isEnemyShot != isEnemy)
{
hp -= shot.damage;
Destroy(shot.gameObject);
}
}
if (hp <= 0)
{
Destroy(gameObject);
}
(I've reformatted that to be rather more conventional C#, but of course you can use whatever indentation you want.)
You're calling GetComponents (notice the plural) which returns an array (that is ShotScript[]) of all matching components of the type on that particular GameObject.
So this is attempting to assign a ShotScript[] array into a single ShotScript instance which is not possible.
If you wanted to retrieve only one ShotScript (because you intend to have only 1 on an object), use the GetComponent (notice the singular) method instead which will return only one instance or null if none are assigned.
So change the one line to this:
ShotScript shot = collider.gameObject.GetComponent<ShotScript>();
If your intent was to handle many ShotScript instances/components on the same GameObject, use the fix/code supplied in Jon Skeet's answer.
The error message says that line 13 is in error:
ShotScript shot = collider.gameObject.GetComponents<ShotScript>();
It looks like the GetComponents method is returning an array ShotScript[], but you're trying to implicity cast it to just a single ShotScript instance. Try:
ShotScript[] shots = collider.gameObject.GetComponents<ShotScript>();

Vector2 2D arrays in XNA

I am trying to create 2D vector2 arrays in XNA,C#.
I used the following statement:
Vector2[][] SpritePosition=new Vector2[4][];
Then I used the following for loop to initialize them:
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
}
}
However, when I used the for loop, as stated above, it gave me an error, actually two:
Int is a field and used as a type.
'for' is an invalid token in class, struct or interface member declaration.
Can anyone tell why am I facing such a problem?
EDIT: This is the code:
public class Game1 : Microsoft.Xna.Framework.Game
{
int i=new int();
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D texture;
//Vector2[,] SpritePosition = new Vector2[4,4];
Vector2[,] SpriteSpeed = new Vector2[4,4];
for(i=0;i<4;i++)
{
}
}
Seems you need to read up on some C# Tutorials
You are going to need a function for that as so,
void LoadArray()
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
SpritePosition[i,j] = new Vector2(i,j)
}
}
You can call it from your initialize method, using LoadArray()
}
Also, You dont need int i = new Int() for basic stuff like strings, ints, etc you dont need the new Whatever() part
Just do
for(int i=0;i<4;i++)
{
}
for #2, it means your for loop isn't inside of a function... so there's probably an extra } somewhere higher up in your code that you didn't mean to put there. there's a good chance that this is also the problem with #1 but you haven't really given us enough context (more code or where exactly the compiler says the error is) to say for sure

Categories