Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Functions with Vector3 argument not showing up in UnityEvent

Discussion in 'Scripting' started by DZZc0rd, Mar 14, 2023.

  1. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I need a function that will save the Vector3 data to a script variable that can be called from a UnityEvent but it doesn't show up. I really need a solution

    Version: 2021.3.14f1
    Code:
    Code (CSharp):
    1. public void test(Vector3 pos)
    2. {
    3.     newPos = pos;
    4. }
    Thank you if you find a solution
     
  2. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    Code (CSharp):
    1. public static TestEvent testEvent = new TestEvent();
    2. public class TestEvent : UnityEvent<Vector3>{}
    3.  
    4. private void OnDisable()
    5. {
    6.     testEvent.RemoveListener(OnTestEvent);
    7. }
    8. private void OnEnable()
    9. {
    10.     testEvent.AddListener(OnTestEvent);
    11. }
    12.  
    13. private void SomeFunction()
    14. {
    15.     testEvent.Invoke(new Vector3(1, 2, 3);
    16. }
    17. private void OnTestEvent(Vector3 _vector)
    18. {
    19.     Debug.Log(_vector);
    20. }
    little bit of jargon. Its really rather simple, unless im missing something in your problem.
     
  3. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    Thanks, but I meant in the editor
     
  4. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    i dont follow. What in editor? Whats not in the editor?

    Code (CSharp):
    1. public TestEvent testEvent = new TestEvent();
    2. [System.Serializable]
    3. public class TestEvent : UnityEvent<Vector3>{}
    that will make an event show in in the inspector, if thats what you mean? I dont think i get what you mean at all.
     
  5. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I mean in this
    upload_2023-3-14_17-32-18.png
     
  6. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    The vector 3 will be passed through as dynamic. as long as you provide a function that indeed passed a vector3.

    You want the vector3 to be showing in the inspector?
     
  7. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    Yes, as argument of function
     
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    You may expect to provide a static vector3 value to your otherwise parameterless event? That's not possible since UnityEvents only support very basic values types or UnityEngine.Object references as static parameters. The only values that are supported as static arguments are those supported by the ArgumentCache class of the UnityEvent system. Specifically: a single int, float, string, bool or UnityEngine.Object value. Those are the only values you can statically specify inside the inspector for a single staticly provided argument.

    When the actual event type accepts dynamic arguments, it would support any kind of argument type and up to 4?! arguments. Though in that case you can not staticly choose values passed to the callback / method in the inspector. Instead the caller of the event has to pass the arguments along.
     
    Homicide likes this.
  9. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    This is sad, I really need this, is there an alternative?
     
  10. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    I dont understand the issue here. If the value you need to be passed through is static, just set teh variable inside the script somewhere, if not, then take advantage of the dynamic method / value.

    Whats the niche case you are trying to resolve?
     
    Bunny83 likes this.
  11. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    It depends on your specific usecase. You can specify the argument as a separate variable next to the event and pass it along when you actually call the event. What's your exact usecase here? What is that vector used for?
     
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    Exactly my thought :)
     
  13. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I making point & click game and I want to implement interaction
     
  14. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    Unfortunately, i think we would need a little more context to assist in this situtation. For the most part, the ins and outs of the event have been covered. Whats missing is the exact useage and expected outcome.
     
  15. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    You can always create small delegate components. That's not that clean but would work just fine.

    Code (CSharp):
    1. public class StaticVector3Delegate : MonoBehaviour
    2. {
    3.     public UnityEvent<Vector3> myEvent;
    4.     public Vector3 argument;
    5.     public void Run()
    6.     {
    7.         myEvent(argument);
    8.     }
    9. }
    10.  
    Not tested, just written from scratch. Though you should get the idea. You can attach this component either to the receiver or the sender, hook up your Vector3 methods in myEvent and have the actual event call the Run method. You can specify the value you want to pass along in the "argument" value of that component.
     
    Homicide likes this.
  16. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    But how dirty would it be to hard-code a Vector3 value in an event call like that? What would that Vector3 value actually represent?
     
  17. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I need to call UnityEvent when the player clicks on an object
     
  18. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    This is new position for player
     
  19. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    Then, how could a hard coded value be of any use? I really think you would want to use dynamics, but again, maybe im still missing a large piece of the pie. :p
     
  20. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    To move player I want use Vector3.lerp function
     
  21. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    I can accept that, no problem, but what has me baffled, is, if your player is moving around, then how is a one time set vector any use at all in this situation? If its set one time and only one time, then really, the player isnt going anywhere, ever, in any time...

    Anywho, i do a little casual tutoring here and there on discord, if you dont mind a screenshare and explaining your use case, im around, hit me up if you want. JD#1539
     
  22. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    Lerp function doesn't work fully in not update function
     
  23. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    But wouldn't it make much more sense to pass a Transform component as target position? You can use empty gameobjects as target markers. Those could also encode an orientation besides a position. You can pass UnityEngine.Object references which includes Transform references to an event.
     
  24. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    657
    Lerp functions fine outside of an update function, provided the function it is running in has some form of iteration and a way of keeping / tracking time itself, for eg: a coroutine.
     
  25. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I think no
     
  26. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,610
    Don't think, do.

    Give it a shot. Using transforms to define positions is a lot better than manually tying out positions.

    Otherwise you're making this unduly hard for yourself.
     
    arkano22 likes this.
  27. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    I think, this is best way which I can choose, Thank you.

    And will there be a big optimization if this point is disabled when moving until the player moves to another
     
  28. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,610
    Well I'm not sure why you made this thread then, as you have deigned to refuse every valid suggestion provided to you.

    Just go the transform route mate.
     
  29. Fira-Soft

    Fira-Soft

    Joined:
    Sep 9, 2014
    Posts:
    26
    I think the solution is to use UltEvents, that is a robust thirdparty package that gives alot more options when handling events.
    The only downside is that you need the actual package, and you will need to add a UltEvent component and link it to yout UnityEvent, calling its Invoke method. There is a tutorial on their site
     
    DZZc0rd likes this.
  30. DZZc0rd

    DZZc0rd

    Joined:
    Sep 4, 2021
    Posts:
    59
    Thank you
     
  31. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,965
    I'm always amazed at how much people underestimate the power of a modern system. You're concerned over an interaction by the user that will happen at most every 50 to 100 milliseconds if in a worse case scenario the user spams it.

    In game development we typically look at milliseconds (thousandths of a second) to determine the performance of task, but these events are taking less than 100 nanoseconds (billionths of a second) to perform which is so far past the point of "you shouldn't care" it's ridiculous.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Diagnostics;
    3. using UnityEngine;
    4. using UnityEngine.Events;
    5.  
    6. public class PerfTest : MonoBehaviour
    7. {
    8.     private Stopwatch stopwatch;
    9.     private UnityEvent<Vector3> vectorEvent;
    10.     private UnityEvent<Transform> transformEvent;
    11.  
    12.     private int vectorEventCount = 0;
    13.     private int transformEventCount = 0;
    14.  
    15.     private void Awake()
    16.     {
    17.         stopwatch = new Stopwatch();
    18.  
    19.         vectorEvent = new UnityEvent<Vector3>();
    20.         vectorEvent.AddListener(OnVectorEvent);
    21.  
    22.         transformEvent = new UnityEvent<Transform>();
    23.         transformEvent.AddListener(OnTransformEvent);
    24.     }
    25.  
    26.     private IEnumerator Start()
    27.     {
    28.         yield return new WaitForSeconds(0.25f);
    29.  
    30.         stopwatch.Start();
    31.         while (stopwatch.ElapsedMilliseconds < 5000)
    32.         {
    33.             vectorEvent.Invoke(Vector3.zero);
    34.             vectorEventCount++;
    35.         }
    36.         stopwatch.Stop();
    37.         print($"Vector3 - Total: {vectorEventCount:n0}");
    38.         print($"Vector3 - Per Second: {vectorEventCount / 5:n0}");
    39.  
    40.         yield return new WaitForSeconds(0.25f);
    41.  
    42.         stopwatch.Restart();
    43.         while (stopwatch.ElapsedMilliseconds < 5000)
    44.         {
    45.             transformEvent.Invoke(this.transform);
    46.             transformEventCount++;
    47.         }
    48.         stopwatch.Stop();
    49.         print($"Transform - Total: {transformEventCount:n0}");
    50.         print($"Transform - Per Second: {transformEventCount / 5:n0}");
    51.     }
    52.  
    53.     private void OnVectorEvent(Vector3 foo) {}
    54.     private void OnTransformEvent(Transform foo) {}
    55. }

    upload_2023-8-25_14-17-51.png
     
    Last edited: Aug 25, 2023
    Bunny83 likes this.