Search Unity

Question How can I check if casting a class to a certain type is valid?

Discussion in 'Visual Scripting' started by Yuchen_Chang, Sep 26, 2022.

  1. Yuchen_Chang

    Yuchen_Chang

    Joined:
    Apr 24, 2020
    Posts:
    126
    Hello!
    Is there a way to check the type-casting result of an input object is valid/invalid?
    Such as, "If the collider of OnCollisionEnter is BoxCollider, then do something".
    I know that there maybe other ways to achieve the same result of the above example, but in real use I'm passing my custom classes to the graph, and hope for a way to do an if/switch process to control the behavior.

    I've already created a node by using SerializableType and seems to be working, but I'm not sure if it is the correct way to do it. Visual Scripting is hiding the SerializableType Deserializing part to be an internal editor feature (-> SerializableTypeExtensions), so I'm not sure if that means I shouldn't be checking the type during runtime.

    Just for someone curios, below is my code and the result node:

    Code (CSharp):
    1. using System;
    2. using Unity.VisualScripting;
    3. using UnityEngine.Scripting;
    4.  
    5. [Preserve]
    6. public class TypeCastNode : Unit
    7. {
    8.     [Serialize, Inspectable, UnitHeaderInspectable]
    9.     public SerializableType serializableCastType;
    10.     private Type castType;
    11.  
    12.     [DoNotSerialize]
    13.     public ControlInput inputTrigger;
    14.  
    15.     [DoNotSerialize]
    16.     public ValueInput inputObject;
    17.  
    18.     [DoNotSerialize]
    19.     [PortLabel("IsNotNull")]
    20.     public ControlOutput isNotNullOutputTrigger;
    21.  
    22.     [DoNotSerialize]
    23.     [PortLabel("IsNull")]
    24.     public ControlOutput isNullOutputTrigger;
    25.  
    26.     [DoNotSerialize]
    27.     public ValueOutput outputCastResultObject;
    28.  
    29.     protected override void Definition()
    30.     {
    31.         inputTrigger = ControlInput("input", CheckCastResult);
    32.         isNotNullOutputTrigger = ControlOutput("IsNotNull");
    33.         isNullOutputTrigger = ControlOutput("IsNull");
    34.  
    35.         inputObject = ValueInput<object>("object");
    36.         DeserializeType();
    37.         if (castType != null) {
    38.             outputCastResultObject = ValueOutput(castType, "cast result", (flow) => flow.GetValue(inputObject));
    39.         }
    40.     }
    41.  
    42.     private void DeserializeType()
    43.     {
    44.         castType = Type.GetType(serializableCastType.Identification);
    45.     }
    46.  
    47.     private ControlOutput CheckCastResult(Flow flow)
    48.     {
    49.         var obj = flow.GetValue(inputObject);
    50.  
    51.         var objType = obj?.GetType();
    52.         if (castType != null && objType != null && castType.IsAssignableFrom(objType)) {
    53.             return isNotNullOutputTrigger;
    54.         }
    55.  
    56.         return isNullOutputTrigger;
    57.     }
    58. }
    59.  
     

    Attached Files:

    Last edited: Sep 26, 2022
  2. REDACT3D_

    REDACT3D_

    Joined:
    Nov 8, 2020
    Posts:
    222
    Hum, you say that it's working but not sure if it's right. what makes you say that it's not right if it's working?
    trying to figure out the base question.

    I wonder if just un-checking that "Static" checkbox on the expose node does the trick.
    Or you could use the Get Bounds node without having to expose the entire node.
    May not even be related to your actual question.
     
  3. Yuchen_Chang

    Yuchen_Chang

    Joined:
    Apr 24, 2020
    Posts:
    126
    Thanks for your reply!
    Currently it's working good, and after some day of using it without any bug, I think it's fine.

    The only concern is that, in fact Unity has already implemented the same feature of "SerializableType-> System.Type" converting, but keep it as an extension method, internal and editor-only feature, so I wonder is there any reason why Unity tried to prevent the feature from being ported to the game.
    (performance issues? or some bug that only happen in specific case?)