• ue4 weapon


    UE4版本4.17,不同版本api可能有差异

    静态



    1 在骨骼上加socket

    在socket上右键-添加浏览资源-找到要添加的那个道具(这个只用来看效果,调位置,不会显示到最终效果中),调整socket位置,知道道具位置合适为止


    2 在角色bp上,添加一个staticMesh到Mesh节点下


    设置父项插槽到刚才创建的socket,选择自己要使用的道具模型




    动态(蓝图)

    1 创建骨骼socket,步骤同上

    2  用蓝图创建跟上面静态一样的结构

    注意使用蓝图和c++创建出来的staticMeshComp运行时,在角色蓝图位置是看不到的,原因未知,但武器是正确显示的




    动态(代码)



    效果跟上面蓝图一样
    先设置socket,然后...
    MyCharacter.h
    // Fill out your copyright notice in the Description page of Project Settings.
    
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Pawn.h"
    #include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h"
    #include "GameFramework/Character.h"
    #include "TLog.h"
    #include "Runtime/Engine/Classes/Engine/EngineTypes.h"
    #include "Runtime/Engine/Classes/Components/InputComponent.h"
    #include "Runtime/Engine/Classes/Components/StaticMeshComponent.h"
    #include "Runtime/Engine/Classes/Engine/SkeletalMeshSocket.h"
    #include "MyCharacter.generated.h"
    
    UCLASS()
    class NDEMO_CHANGEWEAPON_API AMyCharacter : public ACharacter
    {
    	GENERATED_BODY()
    
    public:
    	// Sets default values for this character's properties
    	AMyCharacter();
    
    protected:
    	
    	virtual void BeginPlay() override;
    
    public:	
    	
    	virtual void Tick(float DeltaTime) override;
    
    	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    
    	//这里武器加载的是个单独的UStaticMeshComp
    	void WeaponAttach1();
    	void WeaponDettach1();
    	
    	//之类武器加载的是个Actor类型的蓝图,这种较好,方便做复合物体一起绑到角色身上
    	void WeaponAttach2();
    	void WeaponDettach2();
    
    	UStaticMesh* TUStaticMesh;
    };
    



    MyCharacter.cpp
    #include "MyCharacter.h"
    
    AMyCharacter::AMyCharacter()
    {
    	PrimaryActorTick.bCanEverTick = true;
    	static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("StaticMesh'/Game/model/Effects/Meshes/Items/S_Sword_Basic.S_Sword_Basic'"));
    	if (SphereVisualAsset.Succeeded())
    	{
    		TUStaticMesh = SphereVisualAsset.Object;
    	}
    }
    
    void AMyCharacter::BeginPlay()
    {
    	Super::BeginPlay();
    }
    
    
    void AMyCharacter::Tick(float DeltaTime)
    {
    	Super::Tick(DeltaTime);
    }
    
    void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
    	Super::SetupPlayerInputComponent(PlayerInputComponent);
    	//测试默认按钮绑定,不用再手动设置输入
    
    	InputComponent->BindAction("Custom_Z", IE_Pressed, this, &AMyCharacter::WeaponAttach1);
    	InputComponent->BindAction("Custom_X", IE_Pressed, this, &AMyCharacter::WeaponDettach1);
    
    	InputComponent->BindAction("Custom_V", IE_Pressed, this, &AMyCharacter::WeaponAttach2);
    	InputComponent->BindAction("Custom_B", IE_Pressed, this, &AMyCharacter::WeaponDettach2);
    }
    
    void AMyCharacter::WeaponAttach1()
    {
    	UE_LOG(TLog, Warning, TEXT("WeaponAttach1"));
    	UStaticMeshComponent* C = NewObject<UStaticMeshComponent>(this, "TestWeapon");
    	this->AddOwnedComponent(C);
    	C->RegisterComponent();
    	C->SetStaticMesh(TUStaticMesh);
    	C->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
    	C->SetWorldScale3D(FVector(0.8f));
    	C->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, TEXT("hand_right_socket"));
    
    }
    
    void AMyCharacter::WeaponDettach1() 
    {
    	UE_LOG(TLog, Warning, TEXT("WeaponDettach1"));
    }
    
    void AMyCharacter::WeaponAttach2()
    {
    	
    
    	TSubclassOf<AActor> WeaponClass = LoadClass<AActor>(NULL, TEXT("Blueprint'/Game/item/TWeapon.TWeapon_C'"));
    	
    	AActor* MeleeWeapon = GetWorld()->SpawnActor<AActor>(WeaponClass, FVector(0,0,0), FRotator(0,0,0));
    
    	if (MeleeWeapon)
    	{
    		//通过名字获得骨骼绑点
    		const USkeletalMeshSocket *socket = GetMesh()->GetSocketByName("hand_right_socket");
    		//绑定武器模型到骨骼挂点上
    		socket->AttachActor(MeleeWeapon, GetMesh());
    	}
    	
    }
    
    void AMyCharacter::WeaponDettach2()
    {
    	UE_LOG(TLog, Warning, TEXT("WeaponDettach2"));
    }





    Loaction Rule说明

    http://www.devqinwei.com/2016/11/03/ue4-%E5%B0%86actor-acttach-to-%E5%8F%A6%E4%B8%80%E4%B8%AAactor%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E7%9A%84/

    这里要注意Loaction Rule有三种:Keep Relative , Keep World,Snap to Target。
    Keep Relative:
    将actor在当前场景中的transform移到parent(Socket)中。(当actor在world中处于原始transform时,它最终效果就是在Socket的预览中的效果。
    Keep World:
    保持actor在当前场景中的transform,对socket设置transform没有意义。但如果socket移动旋转缩放,会跟随相应移动旋转缩放。
    Snap to Target:(最常使用)
    使用Socket设置的transform,最终效果与actor在当前场景中的transform无关,最终效果等于socket中预览看到的效果。
    DetachFromActor要注意,只有Keep Relative和Keep World选项。
    如果使用 Snap to Target 进行attach,那么Keep World让Detach之后对保持之前在Socket调整后的最终尺寸到新的场景中(建议使用该方法);如果使用Keep Relative,则会让尺寸使用物体原始尺寸。


    特殊问题记录

    新建character蓝图,actor类型weapon蓝图(里面包含一个staticMesh)
    直接把weapon蓝图拖到character的节点上,运行,character会自动移动,原因跟物理有关,weapon中staticMesh默认Collider设置的是BlockAllDynamic,这个只要改成不跟character碰撞就不会使character自动飞走
    奇怪的是,如果直接向character上加一个staticMesh collider也设置成BlockAllDynamic却是没问题的

    这个问题无论是直接拖动节点,或是代码动态绑都存在


  • 相关阅读:
    postman使用感言
    20. 有效的括号
    13. 罗马数字转整数
    qsort / bsearch
    堆排序(heapsort)
    递归Recursion
    拓扑排序
    N/A的含义
    初级系列17.爱因斯坦的数学题问题
    初级系列16.求车速问题
  • 原文地址:https://www.cnblogs.com/nafio/p/9137032.html
Copyright © 2020-2023  润新知