选中物体后自定义显示内容

先列代码:

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Components/PrimitiveComponent.h"
#include "PaladinNPCPathLineComponent.generated.h"

class FPrimitiveSceneProxy;

UCLASS(BlueprintType, Blueprintable, meta = (BlueprintSpawnableComponent))
class PALADINSEVEN_API UPaladinNPCPathLineComponent : public UPrimitiveComponent
{
	GENERATED_UCLASS_BODY()

public:
	UFUNCTION(BlueprintImplementableEvent, DisplayName = "GetNPCPathPoints")
	void K2_GetNPCPathPoints(TArray<FVector>& PointsArray)const;

public:
	//~ Begin UObject Interface
	virtual void Serialize(FArchive& Ar) override;
	virtual void PostLoad() override;
#if WITH_EDITOR
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
	//~ End UObject Interface

#if !UE_BUILD_SHIPPING
	//~ Begin UPrimitiveComponent Interface.
	virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
	//~ End UPrimitiveComponent Interface.

	//~ Begin USceneComponent Interface
	virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override;
	//~ End USceneComponent Interface

#endif

	//~ Begin UPrimitiveComponent Interface.
	virtual bool IsZeroExtent() const override;
	virtual struct FCollisionShape GetCollisionShape(float Inflation = 0.0f) const override;
	virtual bool AreSymmetricRotations(const FQuat& A, const FQuat& B, const FVector& Scale3D) const override;
	//~ End UPrimitiveComponent Interface.

protected:
	TArray<FVector> Points;
};

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.


#include "PaladinNPCPathLineComponent.h"
#include "WorldCollision.h"
#include "PrimitiveSceneProxy.h"
#include "SceneManagement.h"
#include "Engine/CollisionProfile.h"


UPaladinNPCPathLineComponent::UPaladinNPCPathLineComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	BodyInstance.SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);

	bIsEditorOnly = true;
	bGenerateOverlapEvents = false;
}

#if !UE_BUILD_SHIPPING
FPrimitiveSceneProxy* UPaladinNPCPathLineComponent::CreateSceneProxy()
{
	class FDrawNPCPathSceneProxy final : public FPrimitiveSceneProxy
	{
	public:
		SIZE_T GetTypeHash() const override
		{
			static size_t UniquePointer;
			return reinterpret_cast<size_t>(&UniquePointer);
		}

		FDrawNPCPathSceneProxy(const UPaladinNPCPathLineComponent* InComponent)
			: FPrimitiveSceneProxy(InComponent)
			, bDrawOnlyIfSelected(true)
		{
			bWillEverBeLit = false;
		}

		virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
		{
			const FMatrix& LocalToWorld = GetLocalToWorld();

			for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
			{
				if (VisibilityMap & (1 << ViewIndex))
				{
					const FSceneView* View = Views[ViewIndex];
					const FLinearColor DrawLineColor = FLinearColor::Blue;

					FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex);

					int ArrNum = Points.Num() - 1;

					for (int i = 0;i<ArrNum;++i)
					{
						PDI->DrawLine(Points[i], Points[i + 1], DrawLineColor, SDPG_World,10.0f);
					}
					//DrawWireCapsule(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetScaledAxis(EAxis::X), LocalToWorld.GetScaledAxis(EAxis::Y), LocalToWorld.GetScaledAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World);
				}
			}
		}

		virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
		{
			const bool bProxyVisible = !bDrawOnlyIfSelected || IsSelected();

			FPrimitiveViewRelevance Result;
			Result.bDrawRelevance = (IsShown(View) && bProxyVisible);
			Result.bDynamicRelevance = true;
			Result.bShadowRelevance = IsShadowCast(View);
			//Result.bEditorPrimitiveRelevance = UseEditorCompositing(View);
			Result.bSeparateTranslucencyRelevance = Result.bNormalTranslucencyRelevance = IsShown(View);

			return Result;
		}
		virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); }
		uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); }

		void SetPoints(const TArray<FVector>& Arr) { Points = Arr; }
	private:
		const uint32	bDrawOnlyIfSelected : 1;
		TArray<FVector> Points;
	};

	FDrawNPCPathSceneProxy* Proxy = new FDrawNPCPathSceneProxy(this);
	K2_GetNPCPathPoints(Points);
	Proxy->SetPoints(Points);
	return Proxy;
}

FBoxSphereBounds UPaladinNPCPathLineComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FBox MyBounds;
	MyBounds.Init();
	MyBounds = FBox(FVector(-HALF_WORLD_MAX, -HALF_WORLD_MAX, -HALF_WORLD_MAX), FVector(HALF_WORLD_MAX, HALF_WORLD_MAX, HALF_WORLD_MAX));
	return MyBounds;

/*
    FBox BoundingBox(ForceInit);

	if (Points.Num()<= 0)
	{
		return Super::CalcBounds(LocalToWorld);
	}

	for (const auto& InterpPoint : Points)
	{
		BoundingBox += InterpPoint;
	}

	return FBoxSphereBounds(BoundingBox);
	*/
}
#endif

void UPaladinNPCPathLineComponent::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);
}

void UPaladinNPCPathLineComponent::PostLoad()
{
	Super::PostLoad();
}

#if WITH_EDITOR
void UPaladinNPCPathLineComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
}
#endif	// WITH_EDITOR

bool UPaladinNPCPathLineComponent::IsZeroExtent() const
{
	return false;
	//return (CapsuleRadius == 0.f) && (CapsuleHalfHeight == 0.f);
}


FCollisionShape UPaladinNPCPathLineComponent::GetCollisionShape(float Inflation) const
{
	return Super::GetCollisionShape(Inflation);
}

bool UPaladinNPCPathLineComponent::AreSymmetricRotations(const FQuat& A, const FQuat& B, const FVector& Scale3D) const
{
	return Super::AreSymmetricRotations(A,B,Scale3D);
}

绘制的部分在CreateSceneProxy内完成,而裁剪使用的Bound在CalcBounds中进行计算,上面的代码用的是最大的Bound所以肯定会显示(在物体选中的情况下),注释的代码就是计算这些点的一个有效的Bound的。

选中的时候:

 

这个组件有很多用途,比如策划给NPC配置一些寻路点,这些寻路组成了这个NPC行走的路线,但是策划希望点击NPC的时候能够显示出路线信息,那么这个组件就可以完成这个任务。如果你要写一个带图形的自定义控件,那么你肯定会涉及到这方面的东西。

在Unity中,你可以通过创建自定义的Mesh来创建自定义几何体。以下是创建自定义几何体的步骤: 1. 打开Unity编辑器,创建一个空物体,将其命名为你想要的几何体名称。 2. 点击菜单栏上的“GameObject” → “3D Object” → “Cube”,创建一个正方体。 3. 选中正方体,在Inspector面板中点击“Add Component”按钮,选择“Mesh Filter”和“Mesh Renderer”组件。 4. 在Hierarchy面板上选中你的自定义几何体,然后在Inspector面板上点击“Add Component”按钮,选择“Mesh Filter”组件。 5. 在Hierarchy面板上选中你的自定义几何体,然后在Inspector面板上点击“Add Component”按钮,选择“Mesh Renderer”组件。 6. 在Assets面板上创建一个新的文件夹,将其命名为“Meshes”。 7. 在Assets面板上右键单击文件夹“Meshes”,选择“Create” → “Mesh”。 8. 选中新创建的Mesh,然后在Inspector面板中点击“Edit”按钮,打开Mesh编辑器。 9. 在Mesh编辑器中,你可以使用“Vertex”、“Edge”和“Face”工具来创建你想要的自定义几何体。 10. 当你完成了自定义几何体的创建后,点击Mesh编辑器中的“Save”按钮,将其保存到之前创建的“Meshes”文件夹中。 11. 在Inspector面板中,将Mesh Filter组件中的“Mesh”属性设置为你刚刚创建的自定义几何体的Mesh。 12. 现在你的自定义几何体已经创建完成了,你可以将其添加到场景中,并在运行时使用它。 以上就是在Unity中创建自定义几何体的步骤。需要注意的是,自定义的Mesh应该尽量简单,以避免影响性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值