Announcement

Collapse
No announcement yet.

Modular interact system

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Modular interact system

    I'm trying to make a modular interact system that works like that:
    1- All interactable Actors (like a door, a light switch, a shelf...) have a class component called InteractableActor;
    2- When the player looks for the interactable actor and press "F" key, the InteractableActor class attached to the interacted actor will call a function that I have previously defined at the details panel.

    Example: the player looks at the door and press "F" key, so the door oppens. Then he looks at the light switch and press "F" key, so the light switch turns on.

    CONCLUSIOIN: I need to have a field in the details panel that allows me to select a function of interaction for each type of interactable object.

    I'm migrating from Unity Engine, and there I used a code like this:

    Code:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    
    public class InteractableObject : MonoBehaviour
    {
        public UnityEvent onInteract; //The Inspector panel in Unity shows a field to attach a function.
    
        public void Interact() //When player press "F" key, this function is called.
        {
            onInteract.Invoke();
        }
    }

    #2
    GustavoDBP what I'd do:

    - All interactable Actors (like a door, a light switch, a shelf...) have a class component called InteractableActor;
    Create an Interface InteractableActor with Interact() function and implement it in your Actors

    - When the player looks for the interactable actor and press "F" key, the InteractableActor class attached to the interacted actor will call a function that I have previously defined at the details panel.
    When you "collide" with your Actors check if they implement your InteractableActor. Then call Interact().

    - I need to have a field in the details panel that allows me to select a function of interaction for each type of interactable object.
    In your Door Actor just implement open/close inside Interact() function, same for your Light switch.

    https://docs.unrealengine.com/en-US/...ces/index.html

    Comment


      #3
      Would recommend an interface:
      Code:
      // Copyright bla
      
      #pragma once
      
      #include "CoreMinimal.h"
      #include "UObject/Interface.h"
      #include "MYUseInterface.generated.h"
      
      UINTERFACE(MinimalAPI)
      class UMyUseInterface : public UInterface
      {
         GENERATED_BODY()
      
         UMyUseInterface(FObjectInitializer const& ObjectInitializer)
         {}
      };
      
      class MYGAME_API IMyUseInterface
      {
         GENERATED_IINTERFACE_BODY()
      
      public:
         UFUNCTION(Category = "Use", BlueprintNativeEvent, BlueprintCallable)
         void Use(class AController* Controller, FName UseType);
      
         UFUNCTION(Category = "Use", BlueprintNativeEvent, BlueprintCallable)
         void ServerUse(class AController* Controller, FName UseType);
      };
      The pipe that through your player controller:
      Code:
      void AMyPlayerController::UseActor(class AActor* UseTarget, FName UseType)
      {
         if (IsValid(UseTarget))
         {
            if (UseTarget->GetClass()->ImplementsInterface(UMyUseInterface::StaticClass()))
            {
               if (GetLocalRole() < ROLE_Authority)
               {
                  IMyUseInterface::Execute_ClientUse(UseTarget, this, UseType);
                  ServerUseActor(UseTarget, UseType);
               }
               else
               {
                  IMyUseInterface::Execute_ServerUse(UseTarget, this, UseType);
               }
            }
         }
      }
      
      bool AMyPlayerController::ServerUseActor_Validate(class AActor* UseTarget, const FName& UseType)
      {
         return true;
      }
      
      void AMyPlayerController::ServerUseActor_Implementation(class AActor* UseTarget, const FName& UseType)
      {
         UseActor(UseTarget, UseType);
      }
      You can always expand it as required, such as adding a special "AIUse" if they need to do something different.

      How to decide what to interact with - your call.
      e.g. Trace line from center of the screen, be inside a trigger volume.

      After that, GetPlayerController()->UseActor(SomeActor) or Blueprint equivalent.
      Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.

      Comment

      Working...
      X