Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

choose chess piece from menu in unity3d

Discussion in 'UGUI & TextMesh Pro' started by elsharkawey, Aug 26, 2016.

  1. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    i working in code to replace pawn chess piece to other piece i choosing from popup menu in the game by clicking in button if the piece get the last tile i finished the replacing code and the popup buttons menu i want help in how to selecting the piece from buttons menu





    that's a video for what i finished




    my project in the attach files



    notice : only pawn piece and knight moves i did't added other pieces codes yet to test the code play as my video first white pieces then black pieces



    and sorry for my bad english
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    You can create the following in the editor and just hide it. Activate it with SetActive(true), or dynamically create it in your code:

    1. Make a Panel with a Grid Layout, or Vertical Layout whichever you choose
    2. Put a button in it for each piece a pawn can promote to.
    3. Create a public function in your Game Controller that looks like this:
    Code (CSharp):
    1. // hopefully you have some kind of Enum like this already
    2. public enum PieceType {
    3.           King,
    4.           Queen,
    5.          Rook,
    6.          Bishop,
    7.          Knight,
    8.         Pawn
    9. };
    10.  
    11. public void PromotePiece (int type)
    12. {
    13.    switch (type) {
    14.                  case PieceType.Queen:
    15.                              // cdoe to make a queen
    16.                              break;
    17.                  case PieceType.Rook:  
    18.                            // code to make a rook
    19.                           break;
    20.                  // and so on
    21.             }
    22. }
    Now in the editor for each button add an OnClick Event and drag your GameController object onto.. then choose PromtoePiece function from the list. It will automatically make a spot for you to pick an int. For the Queen button choose 1 (King is 0 in our enum), for the Rook button choose 2 and so on.

    Note: If your making these buttons programmatically you have to add the listeners like this in your code:
    Code (CSharp):
    1. Button myButton = Instantiate(PrefabButton);
    2. // this is the code for a queen button.. change the number to
    3. //whatever piece your making
    4. myButton.OnClick.AddListener(delegate {GameController.PromotePiece(1);});
     
  3. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    are this code what you mean ? i get this two errors when i run this code
    in line 18
    Assets/Scripts/mySecondCanvas11.cs(18,18): error CS0266: Cannot implicitly convert type `mySecondCanvas11.PieceType' to `int'. An explicit conversion exists (are you missing a cast?)

    and in line 25
    Assets/Scripts/mySecondCanvas11.cs(25,18): error CS0266: Cannot implicitly convert type `mySecondCanvas11.PieceType' to `int'. An explicit conversion exists (are you missing a cast?)


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. public class mySecondCanvas11 : MonoBehaviour {
    5.  
    6. public enum PieceType {
    7.           King,
    8.           Queen,
    9.          Rook,
    10.          Bishop,
    11.          Kinght,
    12.          Pawn
    13. };
    14. public void PromotePiece (int type)
    15. {
    16.    switch (type) {
    17.                  case PieceType.Queen:
    18.                             // code to make a Queen
    19.                            activeChessman.Remove(selectedChessman.gameObject);
    20.                            Destroy(selectedChessman.gameObject);
    21.                               SpawnChessman(1, x, y);
    22.                            selectedChessman = Chessmans [x,y];  
    23.  
    24.                           break;
    25.                  case PieceType.Rook:
    26.                            // code to make a rook
    27.                           break;
    28.                  // and so on
    29.             }
    30. }
    31. }
    32.  
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Ah my bad.. silly mistake here is a better solution. You could even use this in your entire code to make it easier to read:
    Create a C# Script Labeled Constants. It doesn't have to be attached to anything:
    Code (CSharp):
    1. public static class Constants
    2. {
    3.             public const int PIECE_KING = 0;
    4.             public const int PIECE_QUEEN = 1;
    5.             public const int PIECE_ROOK = 2;
    6.             public const int PIECE_BISHOP = 3;
    7.             public const int PIECE_KNIGHT=4;
    8.             public const int PIECE_PAWN = 5;
    9. }
    Then delete the enum from your class and change the switch statements to this:
    Code (CSharp):
    1. case Constants.PIECE_QUEEN:
    2.  
    3. case Constants.PIECE_ROOK:
    You could then change your SpawnChessman code to look like;
    SpawnChessman(Constants.PIECE_QUEEN,x,y); // as long as spawnChessman function knew 1=Queen.

    The editor will still require numbers like 1,2,3 but everywhere in your code you can use Constants.PIECE_KING and not have to remember which number goes with what piece
     
  5. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    i added the code like that ok

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. public class mySecondCanvas11 : MonoBehaviour {
    5.  
    6. public static class Constants
    7.     {
    8.                 //public const int PIECE_KING = 0;
    9.                 public const int PIECE_QUEEN = 1;
    10.                 public const int PIECE_ROOK = 2;
    11.                 public const int PIECE_BISHOP = 3;
    12.                 public const int PIECE_KNIGHT=4;
    13.                 public const int PIECE_PAWN = 5;
    14.     }
    15.  
    16. public void PromotePiece (int type)
    17. {
    18.    switch (type) {
    19.                  case Constants.PIECE_QUEEN:
    20.                            activeChessman.Remove(selectedChessman.gameObject);
    21.                            Destroy(selectedChessman.gameObject);
    22.                               SpawnChessman(Constants.PIECE_QUEEN,x,y);
    23.                            selectedChessman = Chessmans [x,y];  
    24.  
    25.                           break;
    26.                  case Constants.PIECE_ROOK:
    27.                            // code to make a rook
    28.                           break;
    29.                  // and so on
    30.             }
    31. }
    32. }
    33.  
    and in my main manager script
    i called the function with this line

    Code (CSharp):
    1. if (y == 7)
    2.               {
    3.                 //LINE2
    4.                
    5.                 mySecondCanvas2.SetActive(true);
    6.                 //calling line and the error ine :3          
    7.                  _mySecondCanvas11.PromotePiece();
    8.                
    9. //                activeChessman.Remove(selectedChessman.gameObject);
    10. //                Destroy(selectedChessman.gameObject);
    11.                
    12. //                   SpawnChessman(1, x, y);
    13. //                selectedChessman = Chessmans [x,y];  
    14.                }
    but i get this error

    Assets/Scripts/BoardManager.cs(111,51): error CS1501: No overload for method `PromotePiece' takes `0' arguments
    so what's the wrong ?
     
  6. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    When you call PromotePiece you have to tell it what pice:
    PromotePiece(Constants.PIECE_QUEEN);

    Or if you add it to the OnClick EventHandler Make sure the int is set to the correct number
     
  7. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    ok but how i can acces to other "public static class" like Constants from other script srry im new in csharp?
     
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Ok so a class in c# is like a blueprint. It has data (variables) and functions. You create a new Instance of a class like this:
    Code (CSharp):
    1. MyClass myVariableName = new MyClass();
    This is what Unity is doing when you put a script on an object.. You just don't see it. Your copying all the variables out of that blueprint and getting your own copy of them. (The functions we just get a pointer to.. there is no need to copy the functions every time to every new instance of a class since they stay the same).

    So i can say:

    Code (CSharp):
    1.  myVariableName.SomeVariable = 5;
    Thats fine, I'm setting 5 to MY copy of MyClass. But i can't say:
    Code (CSharp):
    1. MyClass.SomeVariable = 5;
    Thats trying to set the master blueprints variable to 5. which we just can't do.

    However, if you want to make a class that has NO variables (data) there is a cool trick with the keyword static.
    Code (CSharp):
    1. public static class Utility
    2. {
    3.         public const int PIECE_KING = 0;
    4.         public static int  GetMax(int a, int b)
    5.         {
    6.                         if (a>b)
    7.                               return a;
    8.                         else
    9.                                return b;
    10.          }
    11. }
    the static means that its immutable (can't be changed). Its just pure functions. This is useful for Utility functions we might need that don't care about data. The data equivalent of this is const. public const int PIECE_KING=0; means that PIECE_KING will be a permanent int that the program knows about and it can NEVER be modifided. SO when you have a public static class, its like the blueprint is the one and only copy of it and everyone sees it. You don't even have to add it to an object. Any other script can now just say:
    Code (CSharp):
    1. int max = Utility.GetMax(a,b);
    2. int x = Utility.PIECE_KING;
     
  9. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    so are that the right way ?
    Code (CSharp):
    1.  
    2. Constants.PIECE_QUEEN;
    3. mySecondCanvas11.PromotePiece(PIECE_QUEEN);
    i get this error when i write it

    Assets/Scripts/BoardManager.cs(113,54): error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
     
  10. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    No.
    Constants.Piece_QUEEN; is exactly the same as writing
    5; or 16; This doesn't do anything so the compiler spits out an error.
    This is simply just a way to write the number 1 all the time. Its a longer way to write the number one, but in 6 months it will be so much easier to understand what you were doing. Imagine looking at this code:

    Code (CSharp):
    1. if (myPiece == 5)
    2.      // do something
    3. // OR
    4. if (myPiece == Constants.PIECE_KNIGHT)
    5.    // do something
    The second bit of code will be much more obvious than trying to figure out what 5 was.

    So now your Function call PIECE_QUEEN isn't anything. We never declared it a variable, its not a function. Thats why the compiler is spitting out an error. However, Constants.PIECE_QUEEN is something (its the number 1).
    So you should be writing:
    Code (CSharp):
    1. mySecondCanvas11.PromotePiece(Constants.PIECE_QUEEN);
    Just to emphasize this. You could also write:
    Code (CSharp):
    1. mySecondCanvas11.PromotePiece(1);
    Both are the same. Because Constants.PIECE_QUEEN *IS* the number 1. Its just easier to see whats going on when you read the first line of code versus the second
     
  11. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    are ther any way to accesing to private varibales ?
     
  12. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    i get this error
    "Assets/Scripts/mySecondCanvas11.cs(24,49): error CS0120: An object reference is required to access non-static member `BoardManager.SpawnChessman(int, int, int)'"

    n this code did you know how i can fix it ?
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. public class mySecondCanvas11 : MonoBehaviour {
    5.  
    6. public BoardManager _SpawnChessman;
    7. public static class Constants
    8.     {
    9.        
    10.                 //public const int PIECE_KING = 0;
    11.                 public const int PIECE_QUEEN = 1;
    12.                 public const int PIECE_ROOK = 2;
    13.                 public const int PIECE_BISHOP = 3;
    14.                 public const int PIECE_KNIGHT=4;
    15.                 public const int PIECE_PAWN = 5;
    16.     }
    17.  
    18.  
    19. public void PromotePiece (int type)
    20. {
    21.    switch (type) {
    22.                  case Constants.PIECE_QUEEN:
    23.                            //BoardManager.SpawnChessman(1, x, y);
    24.                             BoardManager.SpawnChessman(mySecondCanvas11.Constants.PIECE_QUEEN,x,y);
    25.  
    26.                            //activeChessman.Remove(selectedChessman.gameObject);
    27.                            //Destroy(selectedChessman.gameObject);
    28.    
    29.  
    30.                           break;
    31.                  case Constants.PIECE_ROOK:
    32.                            // code to make a rook
    33.                           break;
    34.                  // and so on
    35.             }
    36. }
    37. }
    38.  
     
  13. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    In this case BoardManager is the master blueprint. Its your class declartion you can't use it. See up top where you declared: public BoardManager _SpawnChessman; _SpawnChessman is OUR copy of BoardManager. You need to use that.
    Code (CSharp):
    1. BoardManager.SpawnChessman(mySecondCanvas11.Constants.PIECE_QUEEN,x,y);
    should be
    Code (CSharp):
    1. _SpawnChessman.SpawnChessman(mySecondCanvas11.Constants.PIECE_QUEEN,x,y);
     
  14. elsharkawey

    elsharkawey

    Joined:
    May 15, 2016
    Posts:
    41
    i changed my code place to my manager script because there are alot of private functions i can't acces to it from other script and i did't get any errors in the compiler but the menu code did't work to check my project by your self the full code in the board manager script