【UE5 C++课程系列笔记】10——动态单播/多播的基本使用

news2024/12/20 13:28:36

目录

概念

申明动态委托

一、DECLARE_DYNAMIC_DELEGATE 

二、DECLARE_DYNAMIC_MULTICAST_DELEGATE

绑定动态委托

一、BindDynamic

二、AddDynamic

三、RemoveDynamic

执行动态委托

​一、Execute 

二、ExecuteIfBound 

三、IsBound

四、Broadcast

动态单播使用示例

一、两个输入参数无返回值 

二、一个输入参数一个返回值 

动态多播使用示例


上一篇:【UE5 C++课程系列笔记】09——多播委托的基本使用-CSDN博客

概念

        动态单播/多播委托基于虚幻的反射系统,可以在蓝图中进行绑定等操作,这使得它在蓝图与 C++ 交互方面非常有用。动态单播只绑定一个函数,而动态多播可以绑定多个函数,与非动态的单播/多播相比,动态单播/多播提供了蓝图可访问性,使其能在蓝图中进行添加绑定、移除绑定以及调用等操作。与动态单播不同的是动态多播委托通常没有返回值。这是因为动态多播委托的主要目的是实现事件广播机制,它会依次调用所有绑定的函数。

申明动态委托

一、DECLARE_DYNAMIC_DELEGATE 

        DECLARE_DYNAMIC_DELEGATE 是虚幻引擎中用于声明动态单播委托类型的宏。动态委托允许在运行时更灵活地绑定函数,并且支持蓝图(UE 的可视化脚本系统)与 C++ 之间的交互。与普通委托相比,动态委托提供了一种更动态的方式来处理事件响应和函数回调,这在构建复杂的游戏系统,尤其是需要在蓝图中方便地配置和处理事件的场景下非常有用。

无参数的动态委托声明:DECLARE_DYNAMIC_DELEGATE (FDelegateName)。

带一个参数的动态委托声明:DECLARE_DYNAMIC_DELEGATE_OneParam (FDelegateName, ParamType, ParamName)。其中 ParamType 是参数类型,ParamName 是参数名称,用于在蓝图等环境中更清晰地标识参数。例如,声明一个带有一个 int 类型参数的动态委托:DECLARE_DYNAMIC_DELEGATE_OneParam (FMyDynamicDelegate, int, MyIntParam)。

二、DECLARE_DYNAMIC_MULTICAST_DELEGATE

        DECLARE_DYNAMIC_MULTICAST_DELEGATE 用于声明动态多播委托类型的宏。动态多播委托同样支持蓝图和 C++ 的交互,并且可以绑定多个函数。当触发这个委托时,所有绑定的函数都会被依次调用,这对于实现事件广播机制,特别是在需要多个对象或函数对同一事件做出响应,且这些响应可能需要在蓝图中灵活配置的场景下非常有用。

无参数的动态多播委托声明:DECLARE_DYNAMIC_MULTICAST_DELEGATE (FDelegateName)。

带一个参数的动态多播委托声明:DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam (FDelegateName, ParamType, ParamName)。例如,声明一个带有一个 float 类型参数的动态多播委托:DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam (FMyDynamicMulticastDelegate, float, MyFloatParam)。

绑定动态委托

一、BindDynamic

   BindDynamic是虚幻引擎(UE)中用于将函数绑定到动态单播委托上的方法,主要用于动态委托。这种绑定方式支持蓝图(UE 的可视化脚本系统)和 C++ 之间的交互,使得在运行时可以灵活地设置委托所关联的函数,并且能够让蓝图方便地对委托事件进行响应。

语法一般为:DelegateInstance.BindDynamic(ObjectPtr, &FunctionPointer)。其中DelegateInstance是委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要绑定的函数的地址。

在如下示例代码中,当玩家与一个物体交互时,触发一个动态委托。

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyInteractable.generated.h"

// 声明一个带有一个FString参数(表示交互物体名称)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnInteract, FString, InteractableName);

UCLASS()
class MYGAME_API AMyInteractable : public AActor
{
    GENERATED_BODY()
public:
    // 定义动态委托实例
    FOnInteract OnInteract;

    void Interact(FString Name)
    {
        // 触发动态委托(如果已经绑定函数)
        OnInteract.ExecuteIfBound(Name);
    }
};

class UMyInteractUI : public UUserWidget
{
public:
    void BindToInteractable(AMyInteractable* Interactable)
    {
        if (Interactable)
        {
            // 将本对象的函数动态绑定到交互物体的委托上
            Interactable->OnInteract.BindDynamic(this, &UMyInteractUI::OnInteractHandler);
        }
    }

    UFUNCTION(BlueprintImplementableEvent)
    void OnInteractHandler(FString InteractableName)
    {
        // 这个函数可以在蓝图中实现具体的UI更新逻辑,比如显示交互物体的名称
        UE_LOG(LogTemp, Warning, TEXT("Interacted with: %s"), *InteractableName);
    }
};

二、AddDynamic

  AddDynamic主要用于将函数绑定到动态多播委托上。它和BindDynamic类似,都是用于动态地将函数关联到委托,但AddDynamic更侧重于多播委托的操作,用于在已经存在的动态多播委托基础上添加新的函数绑定,使得多个函数可以订阅(绑定)到这个委托,当委托被触发(调用Broadcast)时,所有绑定的函数都会被依次调用。

语法为:DynamicMulticastDelegateInstance.AddDynamic(ObjectPtr, &FunctionPointer)。其中DynamicMulticastDelegateInstance是动态多播委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要添加绑定的函数的地址。

在如下示例代码中,当角色释放技能时,通过动态多播委托通知多个系统进行响应。

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyCharacter.generated.h"

// 声明一个带有一个int参数(表示技能ID)的动态多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSkillCast, int, SkillID);

UCLASS()
class MYGAME_API AMyCharacter : public AActor
{
    GENERATED_BODY()
public:
    // 定义动态多播委托实例,并使用UPROPERTY(BlueprintAssignable)使其可在蓝图中绑定
    UPROPERTY(BlueprintAssignable)
    FOnSkillCast OnSkillCast;

    void CastSkill(int SkillId)
    {
        // 触发动态多播委托
        OnSkillCast.Broadcast(SkillId);
    }
};

class USkillEffectUI : public UUserWidget
{
public:
    void BindToCharacter(AMyCharacter* Character)
    {
        if (Character)
        {
            // 将本对象的函数动态绑定到角色的技能释放委托上
            Character->OnSkillCast.AddDynamic(this, &USkillEffectUI::OnSkillCastHandler);
        }
    }

    UFUNCTION(BlueprintImplementableEvent)
    void OnSkillCastHandler(int SkillId)
    {
        // 在这里可以在蓝图中实现显示技能特效等相关逻辑
        UE_LOG(LogTemp, Warning, TEXT("Skill %d cast. Displaying effect..."), SkillId);
    }
};

三、RemoveDynamic

  RemoveDynamic用于从动态委托中移除之前通过BindDynamicAddDynamic绑定的函数。这在对象生命周期结束或者不再需要某个函数对委托事件做出响应时非常重要,可以避免委托在触发时调用已不存在或不需要的函数,从而防止程序出现错误或意外行为。

语法为:DelegateInstance.RemoveDynamic(ObjectPtr, &FunctionPointer)。其中DelegateInstance是委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要移除绑定的函数的地址。

在如下示例代码中,当一个 UI 对象被销毁时,需要从任务进度更新委托中移除它绑定的函数

#include "CoreMinimal.h"
#include "UObject/ObjectPtr.h"
#include "MyQuestSystem.h"
#include "QuestUI.h"

void UQuestUI::UnbindFromQuestSystem(AMyQuestSystem* QuestSystem)
{
    if (QuestSystem)
    {
        // 从任务系统的进度更新委托中移除本对象绑定的函数
        QuestSystem->OnQuestProgressUpdate.RemoveDynamic(this, &UQuestUI::OnQuestProgressUpdateHandler);
    }
}

执行动态委托

一、Execute 

        对于动态委托,Execute用于触发委托所绑定的函数执行。与普通委托类似,它会直接调用绑定的函数。不过在动态委托的语境下,它主要用于触发单播动态委托(通过DECLARE_DYNAMIC_DELEGATE声明的委托),并且要求委托必须已经绑定了函数,否则会导致程序崩溃,因为它不会检查委托是否绑定函数就尝试调用。

        对于无参数的动态委托实例DynamicDelegateInstance,使用DynamicDelegateInstance.Execute()。如果动态委托带有参数,比如声明了一个带有一个int类型参数的动态委托FMyDynamicDelegate,并且已经绑定了函数,在执行时语法为DynamicDelegateInstance.Execute(ParamValue),其中ParamValue是符合委托参数要求的int类型的值。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyInteractableObject.generated.h"

// 声明一个带有一个FString参数(表示交互提示信息)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnInteract, FString, InteractionPrompt);

UCLASS()
class MYGAME_API AMyInteractableObject : public AActor
{
    GENERATED_BODY()
public:
    // 定义动态委托实例
    FOnInteract OnInteract;

    void Interact()
    {
        FString Prompt = "Interact with this object";
        // 假设委托已经绑定了函数,直接执行委托
        OnInteract.Execute(Prompt);
    }
};

class UMyInteractUI : public UUserWidget
{
public:
    void BindToInteractable(AMyInteractableObject* Interactable)
    {
        if (Interactable)
        {
            // 将本对象的函数动态绑定到交互物体的委托上
            Interactable->OnInteract.BindDynamic(this, &UMyInteractUI::OnInteractHandler);
        }
    }

    UFUNCTION(BlueprintImplementableEvent)
    void OnInteractHandler(FString InteractionPrompt)
    {
        // 在蓝图中实现显示交互提示信息的逻辑
        UE_LOG(LogTemp, Warning, TEXT("Interaction prompt: %s"), *InteractionPrompt);
    }
};

二、ExecuteIfBound 

        ExecuteIfBound是一种更安全的执行动态委托的方式,主要用于执行单播动态委托。它会先检查动态委托是否已经绑定了函数,如果已绑定,则执行该函数;如果未绑定,则不执行任何操作,这样可以避免因空指针引用而导致的程序错误。这种方法在不确定委托是否已经绑定函数的情况下非常实用,能够增强程序的健壮性。

        与Execute类似,对于无参数的动态委托实例DynamicDelegateInstance,使用DynamicDelegateInstance.ExecuteIfBound()。如果动态委托带有参数,例如一个带有一个float类型参数的动态委托,语法为DynamicDelegateInstance.ExecuteIfBound(ParamValue),其中ParamValue是符合委托参数要求的float类型的值。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MySkill.generated.h"

// 声明一个带有一个int参数(表示升级后的技能等级)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnSkillLevelUp, int, NewLevel);

UCLASS()
class MYGAME_API AMySkill : public AActor
{
    GENERATED_BODY()
public:
    FOnSkillLevelUp OnSkillLevelUp;

    void LevelUp(int NewLevel)
    {
        // 检查委托是否绑定函数,如果绑定则执行,否则不做任何事
        OnSkillLevelUp.ExecuteIfBound(NewLevel);
    }
};

三、IsBound

   IsBound用于检查动态委托是否已经绑定了函数。它返回一个布尔值,true表示动态委托已经绑定了函数,false表示没有绑定函数。这个方法在需要根据委托的绑定状态来执行不同逻辑的场景中非常有用,比如在触发委托之前先检查是否有函数可供执行,或者在动态配置委托绑定关系后检查绑定是否成功等。

        对于动态委托实例DynamicDelegateInstance,语法为bool IsBound = DynamicDelegateInstance.IsBound();

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyEventSystem.generated.h"

// 声明一个无参数的动态委托
DECLARE_DYNAMIC_DELEGATE(FOnGameEvent);

UCLASS()
class MYGAME_API AMyEventSystem : public AActor
{
    GENERATED_BODY()
public:
    FOnGameEvent OnGameEvent;

    void TriggerEventIfBound()
    {
        if (OnGameEvent.IsBound())
        {
            // 如果委托已经绑定函数,则触发委托
            OnGameEvent.ExecuteIfBound();
        }
        else
        {
            UE_LOG(LogTemp, Warning, TEXT("Event not bound, no function to execute."));
        }
    }
};

四、Broadcast

        对于多播动态委托,应该使用Broadcast方法来触发委托。Broadcast会按照函数绑定的顺序依次调用所有绑定的函数,从而实现事件广播的功能,让多个对象或函数对同一个事件做出响应。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyEventSystem.generated.h"

// 声明一个带有一个int参数(表示事件相关的数值)的多播动态委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMultiEvent, int, EventValue);

UCLASS()
class MYGAME_API AMyEventSystem : public AActor
{
    GENERATED_BODY()
public:
    FOnMultiEvent OnMultiEvent;

    void TriggerEventCorrect(int Value)
    {
        // 正确的用法,使用Broadcast触发多播委托
        OnMultiEvent.Broadcast(Value);
    }
};

动态单播使用示例

一、两个输入参数无返回值 

        在如下代码中,定义了一个名为 ADynamicSingleDelegateActor 的类,用于处理动态单播委托相关的功能。类中提供了初始化委托、调用委托以及释放委托的函数,分别是InitDynamicTwoParamsDelegate、CallDynamicTwoParamsDelegate、ReleaseDynamicTwoParamsDelegate。

头文件:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicSingleDelegateActor.generated.h"

DECLARE_DYNAMIC_DELEGATE_TwoParams(FDynamicDelegate, FString, InName, int32, InMoney);

UCLASS()
class STUDY_API ADynamicSingleDelegateActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ADynamicSingleDelegateActor();

	UFUNCTION(BlueprintCallable)
	void InitDynamicTwoParamsDelegate(FDynamicDelegate InDelegate);

	UFUNCTION(BlueprintCallable)
	void CallDynamicTwoParamsDelegate(FString InStr, int32 InMoney);

	UFUNCTION(BlueprintCallable)
	void ReleaseDynamicTwoParamsDelegate();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

protected:
	FDynamicDelegate DynamicTwoParamsDelegate;
};

源文件:

// Fill out your copyright notice in the Description page of Project Settings.


#include "Delegate/DynamicSingleDelegateActor.h"

// Sets default values
ADynamicSingleDelegateActor::ADynamicSingleDelegateActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

void ADynamicSingleDelegateActor::InitDynamicTwoParamsDelegate(FDynamicDelegate InDelegate)
{
	DynamicTwoParamsDelegate = InDelegate;
}

void ADynamicSingleDelegateActor::CallDynamicTwoParamsDelegate(FString InStr, int32 InMoney)
{
	DynamicTwoParamsDelegate.ExecuteIfBound(InStr, InMoney);
}

void ADynamicSingleDelegateActor::ReleaseDynamicTwoParamsDelegate()
{
	DynamicTwoParamsDelegate.Clear();
}

// Called when the game starts or when spawned
void ADynamicSingleDelegateActor::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ADynamicSingleDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

编译后,在UEEditor中先创建派生自DynamicSingleDelegateActor的蓝图类,这里命名为“BP_DynamicSingleDelegateActor”

将“BP_DynamicSingleDelegateActor”拖入视口

在关卡蓝图中,设置运行开始时执行InitDynamicTwoParamsDelegate来绑定一个委托事件,然后当按下1键时,执行委托事件。

执行效果如下,当按下1键时成功触发绑定的自定义事件

二、一个输入参数一个返回值 

        在如下代码中,初始化委托、调用委托以及释放委托的函数,分别是 InitDynamicTwoParamsOneRetDelegate、CallDynamicTwoParamsOneRetDelegate、ReleaseDynamicTwoParamsOneRetDelegate

头文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicSingleDelegateActor.generated.h"

DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(int32, FDynamicDelegateRetOne, FString, InName);

UCLASS()
class STUDY_API ADynamicSingleDelegateActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ADynamicSingleDelegateActor();

	UFUNCTION(BlueprintCallable)
	void InitDynamicTwoParamsOneRetDelegate(FDynamicDelegateRetOne InDelegate);

	UFUNCTION(BlueprintCallable)
	void CallDynamicTwoParamsOneRetDelegate(FString InStr);

	UFUNCTION(BlueprintCallable)
	void ReleaseDynamicTwoParamsOneRetDelegate();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

protected:
	FDynamicDelegateRetOne DynamicOneParamsOneRetDelegate;
};

源文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "Delegate/DynamicSingleDelegateActor.h"

// Sets default values
ADynamicSingleDelegateActor::ADynamicSingleDelegateActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;
}

void ADynamicSingleDelegateActor::InitDynamicTwoParamsOneRetDelegate(FDynamicDelegateRetOne InDelegate)
{
	DynamicOneParamsOneRetDelegate = InDelegate;
}

void ADynamicSingleDelegateActor::CallDynamicTwoParamsOneRetDelegate(FString InStr)
{
	int32 returnVal = DynamicOneParamsOneRetDelegate.Execute(InStr);
	UE_LOG(LogTemp, Warning, TEXT("return Value: %d"), returnVal);
}

void ADynamicSingleDelegateActor::ReleaseDynamicTwoParamsOneRetDelegate()
{
	DynamicOneParamsOneRetDelegate.Clear();
}

// Called when the game starts or when spawned
void ADynamicSingleDelegateActor::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ADynamicSingleDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

 编译后,在UEEditor中先创建派生自DynamicSingleDelegateActor的蓝图类,这里命名为“BP_DynamicSingleDelegateActor”

打开“BP_DynamicSingleDelegateActor”,在事件开始后调用InitDynamicTwoParamsOneRetDelegate,由于委托有返回值,这里用“Create Event”节点

创建一个匹配函数,在匹配函数内只打印一下传入的参数,并固定返回100

将蓝图“BP_DynamicSingleDelegateActor”拖入视口

在关卡蓝图中,通过按键1调用函数CallDynamicTwoParamsOneRetDelegate,从而执行委托事件

执行效果如下,可以看到成功打印委托的输入输出参数。

动态多播使用示例

        在如下代码中,定义了一个名为 ADynamicMultiDelegateActor 的类,用于处理动态多播委托相关的功能。类中提供了初始化委托、调用委托的函数,分别是InitDynamicMultiThree、CallDynamicMultiThree。 动态多播委托 FDynamicMultiThree带有三个不同类型的参数,用于传递参数信息。

 头文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicMultiDelegateActor.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDynamicMultiThree, FString, InName, int32, InHealth, int32, InMana);

UCLASS()
class STUDY_API ADynamicMultiDelegateActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ADynamicMultiDelegateActor();

	void InitDynamicMultiThree(FDynamicMultiThree InDelegate);

	UFUNCTION(BlueprintCallable)
	void CallDynamicMultiThree(FString InName, int32 InHealth, int32 InMana);

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UPROPERTY(BLUEprintAssignable)
	FDynamicMultiThree DynamicMultiThree;
};

源文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "DynamicMultiDelegateActor.h"

// Sets default values
ADynamicMultiDelegateActor::ADynamicMultiDelegateActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;
}

void ADynamicMultiDelegateActor::InitDynamicMultiThree(FDynamicMultiThree InDelegate)
{
	DynamicMultiThree = InDelegate;
}

void ADynamicMultiDelegateActor::CallDynamicMultiThree(FString InName, int32 InHealth, int32 InMana)
{
	DynamicMultiThree.Broadcast(InName, InHealth, InMana);
}

// Called when the game starts or when spawned
void ADynamicMultiDelegateActor::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ADynamicMultiDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

创建派生自“DynamicMultiDelegateActor”的蓝图类“BP_DynamicMultiDelegateActor”

打开“BP_DynamicMultiDelegateActor”,在事件开始运行时绑定委托事件

在关卡蓝图中,再次绑定委托。通过按键1调用CallDynamicMultiThree函数,从而调用所有绑定到动态多播委托的函数。

可以看到执行效果如下,按一次按键打印了两次“Test”,表示两个绑定的委托事件都成功触发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis篇-19--运维篇1-主从复制(主从复制,读写分离,配置实现,实战案例)

1、概述 Redis的主从复制(Master-Slave Replication)是一种数据冗余机制,它允许将一台Redis服务器的数据复制到其他Redis服务器。在主从复制中,有一台主服务器(Master)和一个或多个从服务器(Sl…

【ORACLE】一个允许关键字作为别名所引起的语法歧义场景

前言 最近在看SQL语法解析器,发现了antlr4提供的PlSql语法树存在一个BUG,然后我顺着这个BUG,构造了一条SQL,在ORACLE执行,如下 然后神奇的事情出现了,这个查询竟然没有返回行!t1表左关联t2&…

【前端】Jquery拍照,通过PHP将base64编码数据转换成PNG格式,并保存图像到本地

目录 一、需求 二、开发语言 三、效果 四、业务逻辑: 五、web端调用摄像头 六、示例代码 1、前端 2、后端 一、需求 web端使用jquery调用摄像头拍照,并使用PHP把base64编码转换成png格式图片,下载到本地。 由于js不能指定图片存储的…

本地摄像头视频流在html中打开

1.准备ffmpeg 和(rtsp-simple-server srs搭建流媒体服务器)视频服务器. 2.解压视频流服务器修改配置文件mediamtx.yml ,hlsAlwaysRemux: yes 3.双击运行服务器。 4,安装ffmpeg ,添加到环境变量。 5.查询本机设备列表 ffmpeg -list_devices true -f dshow -i d…

机器情绪及抑郁症识别算法(六)

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

34. Three.js案例-创建球体与模糊阴影

34. Three.js案例-创建球体与模糊阴影 实现效果 知识点 WebGLRenderer WebGLRenderer 是 Three.js 中用于渲染 3D 场景的核心类。它负责将场景中的对象绘制到画布上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersObject可选参数对象,包…

服务器数据恢复—RAIDZ离线硬盘数超过热备盘数导致阵列崩溃的数据恢复案例

服务器存储数据恢复环境: ZFS Storage 7320存储阵列中有32块硬盘。32块硬盘分为4组,每组8块硬盘,共组建了3组RAIDZ,每组raid都配置了热备盘。 服务器存储故障: 服务器存储运行过程中突然崩溃,排除人为误操…

108. 将有序数组转换为二叉搜索树(java)

题目描述: 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。 示例 1: 输入:nums [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,…

电子应用设计方案-60:智能床垫系统方案设计

智能床垫系统方案设计 一、引言 智能床垫作为智能家居的一部分,旨在为用户提供更舒适的睡眠体验和健康监测功能。本方案将详细描述智能床垫系统的设计理念、功能模块及技术实现。 二、系统概述 1. 系统目标 - 实时监测睡眠状态,包括心率、呼吸、体动等…

YOLOv8目标检测(六)_封装API接口

YOLOv8目标检测(一)_检测流程梳理:YOLOv8目标检测(一)_检测流程梳理_yolo检测流程-CSDN博客 YOLOv8目标检测(二)_准备数据集:YOLOv8目标检测(二)_准备数据集_yolov8 数据集准备-CSDN博客 YOLOv8目标检测(三)_训练模型:YOLOv8目标检测(三)_训…

CSDN数据大屏可视化【开源】

项目简介 本次基于版本3 开源 版本3开源地址:https://github.com/nangongchengfeng/CsdnBlogBoard.git 版本1开源地址:https://github.com/nangongchengfeng/CSDash.git 这是一个基于 Python 的 CSDN 博客数据可视化看板项目,通过爬虫采…

Moretl安全日志采集工具

永久免费: 至Gitee下载 使用教程: Moretl使用说明 使用咨询: 用途 定时全量或增量采集工控机,电脑文件或日志. 优势 开箱即用: 解压直接运行.不需额外下载.管理设备: 后台统一管理客户端.无人值守: 客户端自启动,自更新.稳定安全: 架构简单,兼容性好,通过授权控制访问. 架…

无人机航测系统技术特点!

一、无人机航测系统的设计逻辑 无人机航测系统的设计逻辑主要围绕实现高效、准确、安全的航空摄影测量展开。其设计目标是通过无人机搭载相机和传感器,利用先进的飞行控制系统和数据处理技术,实现对地表信息的全方位、高精度获取。 需求分析&#xff1…

Java学习笔记(13)——面向对象编程

面向对象基础 目录 面向对象基础 方法重载 练习: 继承 继承树 protected super 阻止继承 向上转型 向下转型 区分继承和组合 练习 小结: 方法重载 如果有一系列方法,功能类似,只是参数有所不同,就可以把…

Running CMake (运行 CMake)

Running CMake {运行 CMake} 1. CLion - Create a new CMake project2. Running CMake (运行 CMake)2.1. Building a project (构建项目)2.2. Picking a compiler (指定编译器)2.3. Verbose and partial builds (详细和部分的构建)2.4. Options (选项)2.4.1. Standard options …

穷举vs暴搜vs深搜vs回溯vs剪枝专题一>子集

题目&#xff1a; 两个方法本质就是决策树的画法不同 方法一解析&#xff1a; 代码&#xff1a; class Solution {private List<List<Integer>> ret;//返回结果private List<Integer> path;//记录路径&#xff0c;注意返回现场public List<List<Int…

MTU 使用使用解释

MTU (Maximum Transmission Unit&#xff0c;最大传输单元) 指的是网络链路层 (例如以太网) 能够传输的最大数据帧大小&#xff0c;以字节为单位。理解 MTU 对网络性能和可靠性至关重要&#xff0c;因为它直接影响数据包的分片 (Fragmentation) 和重组。本文档将详细解释 MTU 的…

uniapp v-tabs修改了几项功能,根据自己需求自己改

根据自己的需求都可以改 这里写自定义目录标题 1.数组中的名字过长&#xff0c;导致滑动异常2.change 事件拿不到当前点击的数据&#xff0c;通过index在原数组中查找得到所需要的id 各种字段麻烦3.添加指定下标下新加红点显示样式 1.数组中的名字过长&#xff0c;导致滑动异常…

iOS - 超好用的隐私清单修复脚本(持续更新)

文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候&#xff0c;提交应用到App Store审核&#xff0c;大家应该都收到过类似这样的邮件&#xff1a; Although submission for App Store review was successful, you may want to correct th…

c语言-----数组

基本概念 数组是C语言中一种用于存储多个相同类型数据的数据结构。这些数据在内存中是连续存储的&#xff0c;可以通过索引&#xff08;下标&#xff09;来访问数组中的各个元素。数组的索引从0开始&#xff0c;这是C语言的规定。例如&#xff0c;一个有n个元素的数组&#xff…