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

Question How do I use a function’s return value as a parameter in another function?

Discussion in 'Scripting' started by wattse13, Jul 26, 2021.

  1. wattse13

    wattse13

    Joined:
    Apr 3, 2019
    Posts:
    9
    How do I use a function’s return value as a parameter in another function?


    I am using Unity 2019.4.20f1


    I am currently trying to dynamically set the Game Object value of a button’s OnClick() method. To do this, I am trying to use a delegate event system, which passes along a reference to the clicked-on-GameObject and a couple of functions.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. // Attatched to InspectMenuController GameObject
    6. public class InspectMenuController : MonoBehaviour
    7. {
    8.     private Transform equipTransform;
    9.     private GameObject currentPrefab;
    10.  
    11.     public GameObject useButton;
    12.     public GameObject replaceButton;
    13.  
    14.     private void OnEnable()
    15.     {
    16.         GameEvents.OnMessageSent += SetCurrentPrefab;
    17.     }
    18.     private void OnDisable()
    19.     {
    20.         GameEvents.OnMessageSent -= SetCurrentPrefab;
    21.     }
    22.  
    23.     // This method is called after a GameObject has been clicked on
    24.     // I think it should take the clicked on GameObject reference as a parameter
    25.     // I don't think it is set up correctly
    26.     public void SetCurrentPrefab(GameObject myClickedPrefab)
    27.     {
    28.         GetCurrentPrefab(myClickedPrefab);
    29.     }
    30.  
    31.     // When this function is called by SetCurrentPrefab it should retrun the passed in GameObject parameter as a value
    32.     // I don't think it is set up correctly
    33.     public GameObject GetCurrentPrefab(GameObject myClickedPrefab)
    34.     {
    35.         myClickedPrefab = currentPrefab;
    36.         Debug.Log("Made it to GetCurrentPrefab");
    37.         return currentPrefab;
    38.     }
    39.  
    40.     // This function should be called with a button OnClick method
    41.     // Ideally, it would use the GetCurrentPrefab return value to dynamically set the GameObject value in the OnClick method
    42.     // I don't think it is set up correctly
    43.     public void CenterPrefab(GameObject currentPrefab)
    44.     {
    45.         currentPrefab = GetCurrentPrefab(currentPrefab);
    46.         if (currentPrefab.TryGetComponent(out EquipmentClass equipment))
    47.         {
    48.             // currentPrefab = myClickedPrefab;
    49.             Debug.Log(equipment.Name);
    50.             Debug.Log("Hi CurrentPrefab");
    51.         }
    52.     }
    53. }
    54.  
    My project is set up in a way that everytime a GameObject is clicked, it triggers a delegate event which passes on a reference to the clicked-on-gameObject to all of the event subscribers. When the delegate event is triggered it calls the function SetCurrentPrefab(GameObject myClickedPrefab). I am using this function mainly to call the next function GetCurrentPrefab(GameObject, myClickedPrefab). Both methods’ arguments should be filled by the currently selected GameObject. However, as I type this I am realizing that I probably don’t have this set up correctly. GetCurrentPrefab() would then return a GameObject as a value, and that GameObject should be the GameObject which was passed along with the delegate event.


    Finally, CenterPrefab(GameObject currentPrefab) should pass in GetCurrentPrefab()’s return value as a parameter for its currentPrefab argument. I am using the out parameter to access the selected-GameObject’s components.


    As it is currently set up, I am given the error: ArgumentException: Object of type 'UnityEngine.Object' cannot be converted to type 'UnityEngine.GameObject'


    When I manually set the OnClick() parameter to the GameObject I am currently testing on I get the error: NullReferenceException: Object reference not set to an instance of an object.

    This error is triggered by line 45, and I think it has something to do with how I’m using the out parameter and the fact that I am probably not passing my GameObject correctly between the previous three functions.


    I’m not sure if this is useful but, in the dropdown menu, I only have one option, CenterPrefab( GameObject), rather than the usual two, static and dynamic.


    I’m not a competent coder, and there is a good chance a lot of this is nonsense as I’m not always sure if I am correctly using terms and what-not. I would be very thankful for any help!
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    Not sure of your exact use case, but generally the pattern is to make and assign anonymous delegates to each individual buttons, each delegate capturing the GameObject you're interested in operating on.

    Here's a discussion of things, particularly the post immediately above mine:

    Delegate / Action variable capture / value capture:

    https://forum.unity.com/threads/dyn...s-with-parameter-passing.974346/#post-6334800
     
    wattse13 likes this.
  3. wattse13

    wattse13

    Joined:
    Apr 3, 2019
    Posts:
    9
    Thanks for the reply!

    I'm rather new to coding, but I think I understand the gist of what you're saying. In a different script, I'm using a delegate to capture the GameObject I want to work on. Is there a way to then pass that captured GameObject to a different delegate, in this case the OnClick()?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    Absolutely... in a vacuum it is hard to understand what you're doing, and once it's part of the delegate call, it's not trivial to pluck it back out, nor is that particularly good design.

    Generally what you want is to pass the GameObject reference itself, then attach it to the new delegate. With your delegate above, you would essentially add / remove a reference to a function which already had a reference to that GameObject.

    Again, hard to explain concretely in a vacuum but you are absolutely on the right track for this. It can bend your brain a bit to straighten it all out, but basically you need to re-wrap the selected GameObject with whatever delegate you want to pass to onClick.
     
    wattse13 likes this.