Announcement

Collapse
No announcement yet.

Victor's improved UseSystem

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

    Victor's improved UseSystem

    I made a few important changes to the Use system i made for the tutorial, now it works both in c++ and blueprints, and you can use blueprint interfaces to implement it, or just implement the IUsable interface in your c++ class. Both work.
    Here you can see a video of how it works purely on blueprints


    You can also implement the IUsable interface in a c++ class, giving you the OnUsed and OnFocus functions.

    Im doing a c++ normal cast in the case the class has the IUsable interface, and then a blueprint style cast for the cases where the blueprint has the interface, but not the c++ class.

    You can see the example code, using the FPS template, here https://github.com/vblanco20-1/Use-System
    you are free to do whatever you want with this code.

    How it works


    The most important part, is the Usable.h and Usable.cpp, if you see Usable.h, you can see this
    Code:
    #pragma once
    #include "Usable.generated.h"
    
    /**This interface has to be added to every Actor that can be used, you have to implement the OnUsed function */
    UINTERFACE(MinimalAPI,Blueprintable)
    class UUsable :public UInterface
    {
    	GENERATED_UINTERFACE_BODY()
    	
    };
    
    class IUsable
    {
    	GENERATED_IINTERFACE_BODY()
    	
    	virtual void OnUsed(AController * user);
    
    	virtual void  OnFocus(AController * user);
    
    	// This will be called by the HUD if you want to display a name in the USE message, leave it empty if you dont want any message
    	virtual FString GetNameToDisplay();
    
    	//This event will be called when the character gets close to an object and presses the Use key.
    	UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "On Used"))
    	void BTOnUsed(AController * user);
    
    	//This event will be called every frame if the object is being watched by the Use System in the HUD
    	UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = " On Focus"))
    	void  BTOnFocus( AController * user);
    };
    The UUsable is the UE4 interface, while the IUsable is the normal c++ interface, as you can see, i have the 2 functions and the 2 blueprint events there.
    When you go to the cpp file, you see this

    Code:
    #include "MyProject.h"
    #include "Usable.h"
    
    UUsable::UUsable(const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer)
    {
    }
    
    //This is required for compiling, would also let you know if somehow you called
    //the base event/function rather than the over-rided version
    void IUsable::OnUsed(AController * user)
    {
    	BTOnUsed(user);
    }
    
    void IUsable::OnFocus(AController * user)
    {	
    	BTOnFocus(user);
    }
    
    
    FString IUsable::GetNameToDisplay()
    {
    	return FString("");
    }
    the 2 inteface functions call the blueprint events by default.
    The character part is this
    Code:
    void AMyProjectCharacter::UseTarget()
    {
    	FHitResult HitTarget;
    	TraceViewTarget(HitTarget);
    	if (HitTarget.GetActor())
    	{
    		// Cast to IUsable for the C++ implementation of the interface
    		IUsable* usable =Cast<IUsable>(HitTarget.GetActor());
    		if (usable)
    		{
    			usable->OnUsed(GetController());
    		}
    		// pure blueprint interfaces wont be casted to IUsable, so we do it with the ImplementsInterface method and call the blueprint directly
    		else if (HitTarget.GetActor()->GetClass()->ImplementsInterface(UUsable::StaticClass()))
    		{
    			IUsable::Execute_BTOnUsed(HitTarget.GetActor(), GetController());
    		}
    	}
    }
    
    void AMyProjectCharacter::Tick(float DeltaSeconds)
    {
    	Super::Tick(DeltaSeconds);
    
    	// trace usable
    	FHitResult HitTarget;
    	TraceViewTarget(HitTarget);
    	if (HitTarget.GetActor())
    	{
    		// Cast to IUsable for the C++ implementation of the interface
    		IUsable* usable = Cast<IUsable>(HitTarget.GetActor());
    		if (usable)
    		{
    			usable->OnFocus(GetController());
    		}
    		// pure blueprint interfaces wont be casted to IUsable, so we do it with the ImplementsInterface method and call the blueprint directly
    		else if (HitTarget.GetActor()->GetClass()->ImplementsInterface(UUsable::StaticClass()))
    		{
    			IUsable::Execute_BTOnFocus(HitTarget.GetActor(), GetController());
    		}
    	}
    }
    void AMyProjectCharacter::TraceViewTarget(FHitResult &HitResult)
    {
    
    	// do a trace from view location, in the direction you are aiming, to get the object under the crosshair
    	FCollisionQueryParams TraceParams("UseTrace", false, this);
    	FVector TraceStart = GetPawnViewLocation();
    	FVector TraceVector = GetBaseAimRotation().Vector();
    	TraceVector.Normalize();
    	FVector TraceEnd = TraceStart + (TraceVector * UseRange);
    	HitResult = FHitResult(ForceInit);
    
    	GetWorld()->LineTraceSingle(HitResult, TraceStart, TraceEnd, ECC_Visibility, TraceParams);
    }
    The TraceViewTarget does a trace from the camera and gives the hitresult, for use the functions. The function USeTarget is what calls the OnUsed functions on the Interface, and the Tick calls the OnFocus.
    The important part is this:
    Code:
                   // Cast to IUsable for the C++ implementation of the interface
    		IUsable* usable = Cast<IUsable>(HitTarget.GetActor());
    		if (usable)
    		{
    			usable->OnFocus(GetController());
    		}
    		// pure blueprint interfaces wont be casted to IUsable, so we do it with the ImplementsInterface method and call the blueprint directly
    		else if (HitTarget.GetActor()->GetClass()->ImplementsInterface(UUsable::StaticClass()))
    		{
    			IUsable::Execute_BTOnFocus(HitTarget.GetActor(), GetController());
    		}
    First, i do an InterfaceCast to do the normal c++ interface, but that does not get the blueprint interface, so it wont detect if the interface is implemented only on blueprint, so i check with ImplementsInterface, and then call the blueprint event directly, with Execute_BTOnFocus() functions, wich takes wich actor to execute the event, and the parameter of the event. This way this system works both in c++ and blueprints, without a problem.
    Last edited by vblanco; 12-05-2014, 02:56 PM.
    UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
    Deep knowlegde of C++ and blueprints. Open to freelance work.
    Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
    http://store.steampowered.com/app/463870
    http://store.steampowered.com/app/500360
    http://store.steampowered.com/app/520750

    #2
    Updated to 4.6
    UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
    Deep knowlegde of C++ and blueprints. Open to freelance work.
    Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
    http://store.steampowered.com/app/463870
    http://store.steampowered.com/app/500360
    http://store.steampowered.com/app/520750

    Comment


      #3
      This looks interesting and I am going to try it out. It also looks like a nice alternative to Tom Looman's UsableActor system, but I do would like to know where the major differences are? It looks like it's easier to use as it's implemented through a interface and not as Actor itself, am I right?

      Greetz,
      Dakraid

      Comment


        #4
        Originally posted by Dakraid View Post
        This looks interesting and I am going to try it out. It also looks like a nice alternative to Tom Looman's UsableActor system, but I do would like to know where the major differences are? It looks like it's easier to use as it's implemented through a interface and not as Actor itself, am I right?

        Greetz,
        Dakraid
        First, this is on c++, not only blueprints, and as an interface. Its power, is that you can just add the interface to whatever you want, both to blueprints, or to a c++ class, and it will work automatically. Making it quite flexible for a lot of things
        UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
        Deep knowlegde of C++ and blueprints. Open to freelance work.
        Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
        http://store.steampowered.com/app/463870
        http://store.steampowered.com/app/500360
        http://store.steampowered.com/app/520750

        Comment


          #5
          Originally posted by vblanco View Post
          First, this is on c++, not only blueprints, and as an interface. Its power, is that you can just add the interface to whatever you want, both to blueprints, or to a c++ class, and it will work automatically. Making it quite flexible for a lot of things
          Thanks for clearing that up.

          I do encounter an issue though: within the TraceViewTarget function you used a variable called UseRange, the problem is that it's nowhere declared (at least not on my end)?
          Any ideas?

          The complete line:
          Code:
          FVector TraceEnd = TraceStart + (TraceVector * UseRange);

          Comment


            #6
            Oh, that is a constant, you should add to the character. Anyway, im going to modify the code to add that Use Range float as a const variable in the TraceViewTarget function so its there.
            UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
            Deep knowlegde of C++ and blueprints. Open to freelance work.
            Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
            http://store.steampowered.com/app/463870
            http://store.steampowered.com/app/500360
            http://store.steampowered.com/app/520750

            Comment


              #7
              Thank you! I also got it to work with my character now and it works fine so far!

              Comment


                #8
                Originally posted by Dakraid View Post
                Thank you! I also got it to work with my character now and it works fine so far!
                Tell me if there is a bug/problem and ill fix it in the repo.
                UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
                Deep knowlegde of C++ and blueprints. Open to freelance work.
                Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
                http://store.steampowered.com/app/463870
                http://store.steampowered.com/app/500360
                http://store.steampowered.com/app/520750

                Comment

                Working...
                X