Search Unity

[Raycast] How make a "collect by key" items

Discussion in 'Scripting' started by szapko, Nov 25, 2016.

  1. szapko

    szapko

    Joined:
    May 4, 2015
    Posts:
    4
    Hello!

    I'm from Poland, so I apologize for errors in my post.

    I would like to make a collect items using the key. I made raycast shows me what object I look, but I can not deal with writing code that I add the item to the inventory. The only thing I can do is to remove it from the scene.

    If I come now to the object, it will be collected for the equipment using the trigger, but i won't that.

    raycast code (the script assigned to the player):
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class playerRaycast : MonoBehaviour {
    5.  
    6.     private RaycastHit point;
    7.     private float distance;
    8.  
    9.     private UnityStandardAssets.Characters.FirstPerson.playerFirstPersonController playerFPC;
    10.  
    11.     private itemAbstract itemAbs;
    12.  
    13.     void Start()
    14.     {
    15.         playerFPC = gameObject.GetComponent<UnityStandardAssets.Characters.FirstPerson.playerFirstPersonController>();
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update() {
    20.         // Dbugowanie celownika
    21.         Vector3 fwd = transform.TransformDirection(Vector3.forward) * 10;
    22.         Debug.DrawRay(transform.position, fwd, Color.red);
    23.  
    24.         if (Physics.Raycast(transform.position, (fwd), out point))
    25.         {
    26.             distance = point.distance;
    27.             print(distance + " " + point.transform.gameObject.name);
    28.  
    29.             if (Input.GetKeyDown(KeyCode.E))
    30.             {
    31.                 Destroy(point.transform.gameObject);
    32.             }
    33.         }
    34.     }
    35. }
    itemAbstract code (the script assigned to the item):
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4.  
    5. public abstract class itemAbstract : MonoBehaviour {
    6.  
    7.     public Texture2D itemIcon;
    8.  
    9.     public string itemName;
    10.     public string itemDescription;
    11.     public string itemType;
    12.     public float itemWeight;
    13.     public float itemStrange; // wytrzymałość
    14.     public bool disposable;
    15.  
    16.     public Texture2D getIcon()
    17.     {
    18.         return itemIcon;
    19.     }
    20.    
    21.     public string getName()
    22.     {
    23.         return itemName;
    24.     }
    25.  
    26.     void OnTriggerEnter(Collider other)
    27.     {
    28.         if(other.tag.Equals("Gracz"))
    29.         {
    30.             other.GetComponent<playerEquipment>().SendMessage("addItem", this);
    31.             Destroy(gameObject);
    32.         }
    33.     }
    34.  
    35.     public abstract bool execute(playerStatistics pS);
    36. }
    playerEquipment code (the script assigned to the player):

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class playerEquipment : MonoBehaviour {
    6.  
    7.     private bool openEquipment;
    8.  
    9.     public Texture2D backgroundEquipment;
    10.  
    11.     // wygląd inwentarza
    12.     public int rows = 5; // kolumny na przedmioty w jednym wierszu
    13.     public int boxWidth = 50;
    14.     public int boxHeight = 50;
    15.     public int boxMargin = 10;
    16.     public Rect positionInventory = new Rect(20, 20, 0, 0);
    17.  
    18.     // Lista przedmiotów
    19.     private List<itemAbstract> listOfItems = new List<itemAbstract>();
    20.  
    21.     // dołączamy kontroler rozgladania się myszka
    22.     private UnityStandardAssets.Characters.FirstPerson.playerFirstPersonController pML;
    23.  
    24.     // odwołanie do statystyk
    25.     private playerStatistics pS;
    26.  
    27.     private playerRaycast pRay;
    28.  
    29.     // odwołanie do menu pauzy
    30.     private pauseMenu pM;
    31.  
    32.     void Start () {
    33.         openEquipment = false;
    34.         pML = gameObject.GetComponent<UnityStandardAssets.Characters.FirstPerson.playerFirstPersonController>();
    35.         pS = gameObject.GetComponent<playerStatistics>();
    36.         pM = gameObject.GetComponent<pauseMenu>();
    37.         pRay = gameObject.GetComponent<playerRaycast>();
    38.  
    39.         positionInventory = new Rect(positionInventory.x, positionInventory.y, ((rows * boxWidth) + ((rows + 1) * boxMargin)), ((rows * boxHeight) + ((rows + 1) * boxMargin)));
    40.     }
    41.    
    42.     void Update () {
    43.         if (pML.setAlive) {
    44.             if (Input.GetKeyUp(KeyCode.Backspace))
    45.             {
    46.                 // otwiera i zamyka ekwipunek
    47.                 openEquipment = !openEquipment;
    48.             }
    49.         }
    50.     }
    51.  
    52.     void OnGUI()
    53.     {
    54.         if(!pM.pausedInfo())
    55.         {
    56.             if (openEquipment)
    57.             {
    58.                 //GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backgroundEquipment); // tło
    59.  
    60.                 int allOfItems = listOfItems.Count; // ilość przedmitów
    61.                 int rowsTab = Mathf.CeilToInt(allOfItems / rows) + 1;
    62.  
    63.                 GUILayout.BeginArea(positionInventory);
    64.                 // rysujemy kafelki na przedmioty
    65.                 for (int i = 0; i < rowsTab; i++)
    66.                 {
    67.                     for (int j = 0; j < rows; j++)
    68.                     {
    69.                         if ((i * rowsTab) + j < allOfItems)
    70.                         {
    71.                             if (GUI.Button(new Rect((boxMargin + boxMargin * j + boxWidth * j), (boxMargin + boxMargin * i + boxHeight * i), boxWidth, boxHeight), listOfItems[(i * rows) + j].getIcon())) // getItemIcon zwraca obiekt typu Texture2D
    72.                             {
    73.                                 bool disposable = listOfItems[(i * rows) + j].execute(pS); // funkcja execute pozwala na wpływanie na wszystko we wskazanym obiekcie. np. zmiana punktow zycia lub pancerz
    74.                                 if (disposable)
    75.                                 {
    76.                                     listOfItems.RemoveAt((i * rows) + j); // usuwa obiekt o konkretnym indeksie
    77.                                 }
    78.                             }
    79.                         }
    80.                         else
    81.                         {
    82.                             if (GUI.Button(new Rect((boxMargin + boxMargin * j + boxWidth * j), (boxMargin + boxMargin * i + boxHeight * i), boxWidth, boxHeight), ""))
    83.                             {
    84.                                 Debug.Log("Clicked the button!");
    85.                             }
    86.                         }
    87.                     }
    88.                 }
    89.                 GUILayout.EndArea();
    90.             }
    91.         }
    92.     }
    93.  
    94.     public void addItem(itemAbstract item)
    95.     {
    96.         listOfItems.Add(item);
    97.     }
    98. }
    Please for help!
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    In PlayerRaycast.cs, add a reference to the inventory at Start:

    Code (csharp):
    1.  
    2.   private itemAbstract itemAbs;
    3.  
    4.   private playerEquipment equipment;
    5.   void Start()
    6.   {
    7.   playerFPC = gameObject.GetComponent<UnityStandardAssets.Characters.FirstPerson.playerFirstPersonController>();
    8.  
    9.   equipment = GetComponent<playerEquipment>();
    10.   }
    11.  
    Then instead of destroy, you want to do:

    Code (csharp):
    1.  
    2.   if (Input.GetKeyDown(KeyCode.E))
    3.   {
    4.   itemAbstract item = point.transform.gameObject.GetComponent<itemAbstract>();
    5.  
    6.   if(item != null)
    7.   equipment.addItem(item);
    8.   }
    9.  
    That should work.
     
    szapko likes this.
  3. szapko

    szapko

    Joined:
    May 4, 2015
    Posts:
    4
    Thank you for your answer, but after the modification when I click on key "e" in the Unity console I have error:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class playerRaycast : MonoBehaviour {
    5.  
    6.     private RaycastHit point;
    7.     private float distance;
    8.  
    9.     private bool canTake = false;
    10.  
    11.     private itemAbstract itemAbs;
    12.     private playerEquipment equipment;
    13.  
    14.     void Start()
    15.     {
    16.         equipment = GetComponent<playerEquipment>();
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update() {
    21.         // Dbugowanie celownika
    22.         Vector3 fwd = transform.TransformDirection(Vector3.forward) * 10;
    23.         Debug.DrawRay(transform.position, fwd, Color.red);
    24.  
    25.         if (Physics.Raycast(transform.position, (fwd), out point))
    26.         {
    27.             distance = point.distance;
    28.             //print(distance + " " + point.transform.gameObject.name);
    29.             if (distance <= 6.0 && point.transform.tag == "item")
    30.             {
    31.                 canTake = true;
    32.                 if (Input.GetKeyDown(KeyCode.E))
    33.                 {
    34.                     itemAbstract item = point.transform.gameObject.GetComponent<itemAbstract>();                    //Destroy(point.transform.gameObject);
    35.  
    36.                     if (item != null)
    37.                     {
    38.                         equipment.addItem(item);
    39.                     }
    40.                 }
    41.             }
    42.             else
    43.             {
    44.                 canTake = false;
    45.             }
    46.         }
    47.     }
    48.  
    49.     void OnGUI()
    50.     {
    51.         if(canTake == true)
    52.         {
    53.             GUI.Box(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 120, 25), "Podnieś");
    54.         }
    55.     }
    56. }
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    That's saying that equipment is null -- are you sure you have the playerEquipment component attached to the same GameObject as the playerRaycast component?
     
    szapko likes this.
  5. szapko

    szapko

    Joined:
    May 4, 2015
    Posts:
    4
    Thanks you very much. :)

    The script raycast was hooked into the camera, and the rest of scripts hooked into the parent object player.

    The collection of works, but encountered a new problem, namely, raycast hooked the player, not the camera, rotate only the right and left, and as I do now turning even up - down.

    Any ideas?
     
  6. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I'm not really sure what perspective your game is, I'm guessing FPS, but you can still access the primary camera via Camera.main, so you can substitute those values into your Raycast:

    Code (csharp):
    1.  
    2. if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out point))
    3.  
     
    szapko likes this.
  7. szapko

    szapko

    Joined:
    May 4, 2015
    Posts:
    4
    Raycast rotates, but faster than the center of the camera and the point is not in the center of the screen, just below and a little more time to the left and once to the right a little more. It depends on how the rotation will execute.

    Code (CSharp):
    1. // Update is called once per frame
    2.     void Update() {
    3.         // Debug
    4.         Vector3 fwd = transform.TransformDirection(Camera.main.transform.forward) * 10;
    5.         Debug.DrawRay(Camera.main.transform.position, fwd, Color.red);
    6.  
    7.        // Camera.main.transform.position, Camera.main.transform.forward
    8.  
    9.         if (Physics.Raycast(Camera.main.transform.position, (fwd), out point))
    10.         {
    11.             distance = point.distance;
    12.             //print(distance + " " + point.transform.gameObject.name);
    13.             if (distance <= 5.5 && point.transform.tag == "item")
    14.             {
    15.                 canTake = true;
    16.                 if (Input.GetKeyDown(KeyCode.E))
    17.                 {
    18.                     itemAbstract item = point.transform.gameObject.GetComponent<itemAbstract>();
    19.                     if (item != null)
    20.                     {
    21.                         equipment.addItem(item);
    22.                         Destroy(point.transform.gameObject);
    23.                     }
    24.                 }
    25.             }
    26.             else
    27.             {
    28.                 canTake = false;
    29.             }
    30.         }
    31.     }



    _________ Edit ___________


    Already problem solved. It turned out that the code should look like this:
    Code (CSharp):
    1.  void Update() {
    2.         // Debug
    3.         Vector3 fwd = Camera.main.transform.TransformDirection(Vector3.forward) * 10;
    4.         Debug.DrawRay(Camera.main.transform.position, fwd, Color.red);
    5.  
    6.        // Camera.main.transform.position, Camera.main.transform.forward
    7.  
    8.         if (Physics.Raycast(Camera.main.transform.position, (fwd), out point))
    9.         {
    10.             distance = point.distance;
    11.             //print(distance + " " + point.transform.gameObject.name);
    12.             if (distance <= 5.5 && point.transform.tag == "item")
    13.             {
    14.                 canTake = true;
    15.                 if (Input.GetKeyDown(KeyCode.E))
    16.                 {
    17.                     itemAbstract item = point.transform.gameObject.GetComponent<itemAbstract>();
    18.                     if (item != null)
    19.                     {
    20.                         equipment.addItem(item);
    21.                         Destroy(point.transform.gameObject);
    22.                     }
    23.                 }
    24.             }
    25.             else
    26.             {
    27.                 canTake = false;
    28.             }
    29.         }
    30.     }
    Additionally, I had to reset the local camera position and the local rotation.
     
    Last edited: Dec 3, 2016