2016.8.30

发现了这个函数,可以直接获得摄像机的位置和旋转。

  1. Controller->GetPlayerViewPoint(CamLoc, CamRot);

最近看了几天PlayerCameraManager的代码,大致看明白了,本着分享的原则,在此分享一些经验。

PlayerCameraManager,顾名思义就是管理角色摄像仪与视角的,你可以通过继承的方式,编写自己的PlayerCameraManager,之后在你角色的控制类中指定即可。

下面说一下主要的运行过程:

这里可以参考一下ShooterGame(ShooterPlayerCameraManager),从函数UpdateCamera开始看

  1. void AShooterPlayerCameraManager::UpdateCamera(float DeltaTime)
  2. {
      //尝试获取角色类指针,如果成功就执行一些第一人称视角相关的修正
  3. AShooterCharacter* MyPawn = PCOwner ? Cast<AShooterCharacter>(PCOwner->GetPawn()) : NULL;
  4. if (MyPawn && MyPawn->IsFirstPerson())
  5. {
        //Fov切换的相关逻辑,(右键的微瞄切换)
  6. const float TargetFOV = MyPawn->IsTargeting() ? TargetingFOV : NormalFOV;
  7. DefaultFOV = FMath::FInterpTo(DefaultFOV, TargetFOV, DeltaTime, 20.0f);
  8. }
  9.   //执行父类函数
  10. Super::UpdateCamera(DeltaTime);
  11.   //对角色类的模型进行变换
  12. if (MyPawn && MyPawn->IsFirstPerson())
  13. {
  14. MyPawn->OnCameraUpdate(GetCameraLocation(), GetCameraRotation());
  15. }
  16. }

  这里并没有视角的相关逻辑,所以进一步看父类的UpdateCamera函数。

  1. void APlayerCameraManager::UpdateCamera(float DeltaTime)
  2. {
  3. if ((PCOwner->Player && PCOwner->IsLocalPlayerController()) || !bUseClientSideCameraUpdates || bDebugClientSideCamera)
  4. {
  5. DoUpdateCamera(DeltaTime);
  6.  
  7. if (GetNetMode() == NM_Client && bShouldSendClientSideCameraUpdate)
  8. {
  9. // compress the rotation down to 4 bytes
  10. int32 const ShortYaw = FRotator::CompressAxisToShort(CameraCache.POV.Rotation.Yaw);
  11. int32 const ShortPitch = FRotator::CompressAxisToShort(CameraCache.POV.Rotation.Pitch);
  12. int32 const CompressedRotation = (ShortYaw << ) | ShortPitch;
  13.  
  14. PCOwner->ServerUpdateCamera(CameraCache.POV.Location, CompressedRotation);
  15. bShouldSendClientSideCameraUpdate = false;
  16. }
  17. }
  18. }

  这里是一些网络的逻辑,继续看DoUpdateCamera函数

  1. void APlayerCameraManager::DoUpdateCamera(float DeltaTime)
  2. {
      //一些后期效果融合
  3. // update color scale interpolation
  4. if (bEnableColorScaleInterp)
  5. {
  6. float BlendPct = FMath::Clamp((GetWorld()->TimeSeconds - ColorScaleInterpStartTime) / ColorScaleInterpDuration, .f, 1.0f);
  7. ColorScale = FMath::Lerp(OriginalColorScale, DesiredColorScale, BlendPct);
  8. // if we've maxed
  9. if (BlendPct == 1.0f)
  10. {
  11. // disable further interpolation
  12. bEnableColorScaleInterp = false;
  13. }
  14. }
  15.   
      
      //是否停止工作,不然就执行UpdateViewTarget
  16. // Don't update outgoing viewtarget during an interpolation when bLockOutgoing is set.
  17. if ((PendingViewTarget.Target == NULL) || !BlendParams.bLockOutgoing)
  18. {
  19. // Update current view target
  20. ViewTarget.CheckViewTarget(PCOwner);
  21. UpdateViewTarget(ViewTarget, DeltaTime);
  22. }
  23.   //下面都是一些视角更新的循环逻辑,看到最后你会发现他们一直都是用的引用,设置新的视角的逻辑并不在这
  24. // our camera is now viewing there
  25. FMinimalViewInfo NewPOV = ViewTarget.POV;
  26.  
  27. // if we have a pending view target, perform transition from one to another.
  28. if (PendingViewTarget.Target != NULL)
  29. {
  30. BlendTimeToGo -= DeltaTime;
  31.  
  32. // Update pending view target
  33. PendingViewTarget.CheckViewTarget(PCOwner);
  34. UpdateViewTarget(PendingViewTarget, DeltaTime);
  35.  
  36. // blend....
  37. if (BlendTimeToGo > )
  38. {
  39. float DurationPct = (BlendParams.BlendTime - BlendTimeToGo) / BlendParams.BlendTime;
  40.  
  41. float BlendPct = .f;
  42. switch (BlendParams.BlendFunction)
  43. {
  44. case VTBlend_Linear:
  45. BlendPct = FMath::Lerp(.f, .f, DurationPct);
  46. break;
  47. case VTBlend_Cubic:
  48. BlendPct = FMath::CubicInterp(.f, .f, .f, .f, DurationPct);
  49. break;
  50. case VTBlend_EaseIn:
  51. BlendPct = FMath::Lerp(.f, .f, FMath::Pow(DurationPct, BlendParams.BlendExp));
  52. break;
  53. case VTBlend_EaseOut:
  54. BlendPct = FMath::Lerp(.f, .f, FMath::Pow(DurationPct, .f / BlendParams.BlendExp));
  55. break;
  56. case VTBlend_EaseInOut:
  57. BlendPct = FMath::InterpEaseInOut(.f, .f, DurationPct, BlendParams.BlendExp);
  58. break;
  59. default:
  60. break;
  61. }
  62.  
  63. // Update pending view target blend
  64. NewPOV = ViewTarget.POV;
  65. NewPOV.BlendViewInfo(PendingViewTarget.POV, BlendPct);//@TODO: CAMERA: Make sure the sense is correct! BlendViewTargets(ViewTarget, PendingViewTarget, BlendPct);
  66. }
  67. else
  68. {
  69. // we're done blending, set new view target
  70. ViewTarget = PendingViewTarget;
  71.  
  72. // clear pending view target
  73. PendingViewTarget.Target = NULL;
  74.  
  75. BlendTimeToGo = ;
  76.  
  77. // our camera is now viewing there
  78. NewPOV = PendingViewTarget.POV;
  79. }
  80. }
  81.  
  82. // Cache results
  83. FillCameraCache(NewPOV);
  84.  
  85. if (bEnableFading)
  86. {
  87. if (bAutoAnimateFade)
  88. {
  89. FadeTimeRemaining = FMath::Max(FadeTimeRemaining - DeltaTime, 0.0f);
  90. if (FadeTime > 0.0f)
  91. {
  92. FadeAmount = FadeAlpha.X + ((.f - FadeTimeRemaining / FadeTime) * (FadeAlpha.Y - FadeAlpha.X));
  93. }
  94.  
  95. if ((bHoldFadeWhenFinished == false) && (FadeTimeRemaining <= .f))
  96. {
  97. // done
  98. StopCameraFade();
  99. }
  100. }
  101.  
  102. if (bFadeAudio)
  103. {
  104. ApplyAudioFade();
  105. }
  106. }
  107. }

  接下来看UpdateViewTarget函数,计算视角的逻辑都在里面

  1. void APlayerCameraManager::UpdateViewTarget(FTViewTarget& OutVT, float DeltaTime)
  2. {
  3. // Don't update outgoing viewtarget during an interpolation
  4. if ((PendingViewTarget.Target != NULL) && BlendParams.bLockOutgoing && OutVT.Equal(ViewTarget))
  5. {
  6. return;
  7. }
  8.   //设置默认属性的摄像机
  9. // store previous POV, in case we need it later
  10. FMinimalViewInfo OrigPOV = OutVT.POV;
  11.   
  12. //@TODO: CAMERA: Should probably reset the view target POV fully here
  13. OutVT.POV.FOV = DefaultFOV;
  14. OutVT.POV.OrthoWidth = DefaultOrthoWidth;
  15. OutVT.POV.bConstrainAspectRatio = false;
  16. OutVT.POV.bUseFieldOfViewForLOD = true;
  17. OutVT.POV.ProjectionMode = bIsOrthographic ? ECameraProjectionMode::Orthographic : ECameraProjectionMode::Perspective;
  18. OutVT.POV.PostProcessSettings.SetBaseValues();
  19. OutVT.POV.PostProcessBlendWeight = 1.0f;
  20.  
  21. bool bDoNotApplyModifiers = false;
  22.   //如果ViewTarget是个摄像机的话,就直接获取摄像机的视角
  23. if (ACameraActor* CamActor = Cast<ACameraActor>(OutVT.Target))
  24. {
  25. // Viewing through a camera actor.
  26. CamActor->GetCameraComponent()->GetCameraView(DeltaTime, OutVT.POV);
  27. }
  28. else
  29. {
  30.     //下面都是一些不同模式的摄像机的逻辑,你可以在游戏中按下~,输入Camera XXXX的方式切换这个摄像机
        //默认的摄像机是Default
  31. static const FName NAME_Fixed = FName(TEXT("Fixed"));
  32. static const FName NAME_ThirdPerson = FName(TEXT("ThirdPerson"));
  33. static const FName NAME_FreeCam = FName(TEXT("FreeCam"));
  34. static const FName NAME_FreeCam_Default = FName(TEXT("FreeCam_Default"));
  35. static const FName NAME_FirstPerson = FName(TEXT("FirstPerson"));
  36.  
  37. if (CameraStyle == NAME_Fixed)
  38. {
  39. // do not update, keep previous camera position by restoring
  40. // saved POV, in case CalcCamera changes it but still returns false
  41. OutVT.POV = OrigPOV;
  42.  
  43. // don't apply modifiers when using this debug camera mode
  44. bDoNotApplyModifiers = true;
  45. }
  46. else if (CameraStyle == NAME_ThirdPerson || CameraStyle == NAME_FreeCam || CameraStyle == NAME_FreeCam_Default)
  47. {
  48. // Simple third person view implementation
  49. FVector Loc = OutVT.Target->GetActorLocation();
  50. FRotator Rotator = OutVT.Target->GetActorRotation();
  51.  
  52. if (OutVT.Target == PCOwner)
  53. {
  54. Loc = PCOwner->GetFocalLocation();
  55. }
  56.  
  57. // Take into account Mesh Translation so it takes into account the PostProcessing we do there.
  58. // @fixme, can crash in certain BP cases where default mesh is null
  59. // APawn* TPawn = Cast<APawn>(OutVT.Target);
  60. // if ((TPawn != NULL) && (TPawn->Mesh != NULL))
  61. // {
  62. // Loc += FQuatRotationMatrix(OutVT.Target->GetActorQuat()).TransformVector(TPawn->Mesh->RelativeLocation - GetDefault<APawn>(TPawn->GetClass())->Mesh->RelativeLocation);
  63. // }
  64.  
  65. //OutVT.Target.GetActorEyesViewPoint(Loc, Rot);
  66. if( CameraStyle == NAME_FreeCam || CameraStyle == NAME_FreeCam_Default )
  67. {
  68. Rotator = PCOwner->GetControlRotation();
  69. }
  70.  
  71. FVector Pos = Loc + ViewTargetOffset + FRotationMatrix(Rotator).TransformVector(FreeCamOffset) - Rotator.Vector() * FreeCamDistance;
  72. FCollisionQueryParams BoxParams(NAME_FreeCam, false, this);
  73. BoxParams.AddIgnoredActor(OutVT.Target);
  74. FHitResult Result;
  75.  
  76. GetWorld()->SweepSingleByChannel(Result, Loc, Pos, FQuat::Identity, ECC_Camera, FCollisionShape::MakeBox(FVector(.f)), BoxParams);
  77. OutVT.POV.Location = !Result.bBlockingHit ? Pos : Result.Location;
  78. OutVT.POV.Rotation = Rotator;
  79.  
  80. // don't apply modifiers when using this debug camera mode
  81. bDoNotApplyModifiers = true;
  82. }
  83. else if (CameraStyle == NAME_FirstPerson)
  84. {
  85. // Simple first person, view through viewtarget's 'eyes'
  86. OutVT.Target->GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
  87.  
  88. // don't apply modifiers when using this debug camera mode
  89. bDoNotApplyModifiers = true;
  90. }
  91. else
  92. {
           //默认摄像机会执行这个函数
  93. UpdateViewTargetInternal(OutVT, DeltaTime);
  94. }
  95. }
  96.   //这个应该是执行CameraShakes的逻辑
  97. if (!bDoNotApplyModifiers || bAlwaysApplyModifiers)
  98. {
  99. // Apply camera modifiers at the end (view shakes for example)
  100. ApplyCameraModifiers(DeltaTime, OutVT.POV);
  101. }
  102.   //头戴设备的视角逻辑
  103. if (bFollowHmdOrientation)
  104. {
  105. if (GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed())
  106. {
  107. GEngine->HMDDevice->UpdatePlayerCameraRotation(this, OutVT.POV);
  108. }
  109. }
  110.  
  111. // Synchronize the actor with the view target results
  112. SetActorLocationAndRotation(OutVT.POV.Location, OutVT.POV.Rotation, false);
  113.   
  114. UpdateCameraLensEffects(OutVT);
  115. }

  综上所述,你应该把摄像机逻辑写在这,如果想了解得更加清楚,可以继续从UpdateViewTargetInternal函数看下去,一直看到CalcCamera为止。

下面大致说一下编写思路:

在使用编辑器新建完自己的CameraManager后,在控制类中制定,例如:

PlayerCameraManagerClass = ADemoCameraManager::StaticClass();

然后我贴一下自己写的代码,这里我实现了一个固定视角:

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #pragma once
  4.  
  5. #include "Camera/PlayerCameraManager.h"
  6. #include "DemoCameraManager.generated.h"
  7.  
  8. /**
  9. *
  10. */
  11. UCLASS()
  12. class DEMO_API ADemoCameraManager : public APlayerCameraManager
  13. {
  14. GENERATED_BODY()
  15. protected:
  16. virtual void UpdateViewTarget(FTViewTarget& OutVT, float DeltaTime) override;
  17.  
  18. //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = TViewTarget)
  19. //struct FMinimalViewInfo SceneFixedPOV;
  20.  
  21. };
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #include "Demo.h"
  4. #include "DemoCameraManager.h"
  5. #include "DemoCharacter.h"
  6.  
  7. void ADemoCameraManager::UpdateViewTarget(FTViewTarget& OutVT, float DeltaTime)
  8. {
  9. if (bFollowHmdOrientation)
  10. {
  11. //如果有VR设备就直接运行引擎原始函数
  12. Super::UpdateViewTarget(OutVT, DeltaTime);
  13. return;
  14. }
  15. // Don't update outgoing viewtarget during an interpolation
  16. if ((PendingViewTarget.Target != NULL) && BlendParams.bLockOutgoing && OutVT.Equal(ViewTarget))
  17. {
  18. return;
  19. }
  20. bool bDoNotApplyModifiers = false;
  21.  
  22. if (ACameraActor* CamActor = Cast<ACameraActor>(OutVT.Target))
  23. {
  24. // Viewing through a camera actor.
  25. CamActor->GetCameraComponent()->GetCameraView(DeltaTime, OutVT.POV);
  26. }
  27. else
  28. {
  29. if (CameraStyle == FName("SceneFixed"))
  30. {
           //这里我感觉可能用PendingViewTarget来传递摄像机坐标和旋转比较好,但是还没测试过
  31. //自己定义一个场景固定视角
  32. ADemoCharacter *Character = Cast<ADemoCharacter>(GetOwningPlayerController()->GetPawn());
  33. OutVT.POV.Location = Character->ViewTargetLocation;
  34. OutVT.POV.Rotation = Character->ViewTargetRotator;
  35. //DesiredView.FOV = FieldOfView;
  36. //DesiredView.AspectRatio = AspectRatio;
  37. // don't apply modifiers when using this debug camera mode
  38. bDoNotApplyModifiers = true;
  39. }else if (CameraStyle==FName("Default"))
  40. {
  41. //默认方式是直接取得摄像机的参数来设置FTViewTarget.pov,而摄像机被控制类、SpringArm控制。
  42. UpdateViewTargetInternal(OutVT, DeltaTime);
  43. }
  44. else
  45. {
  46. Super::UpdateViewTarget(OutVT, DeltaTime);
  47. }
  48. }
  49. if (!bDoNotApplyModifiers || bAlwaysApplyModifiers)
  50. {
  51. // Apply camera modifiers at the end (view shakes for example)
  52. ApplyCameraModifiers(DeltaTime, OutVT.POV);
  53. }
  54. // Synchronize the actor with the view target results
  55. SetActorLocationAndRotation(OutVT.POV.Location, OutVT.POV.Rotation, false);
  56. UpdateCameraLensEffects(OutVT);
  57. }

后面是固定视角VolumeActor的代码:

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #pragma once
  4.  
  5. #include "GameFramework/Actor.h"
  6. #include "Character/DemoCharacter.h"
  7. #include "Character/DemoCameraManager.h"
  8. #include "Character/DemoPlayerController.h"
  9. #include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
  10. #include "BaseSceneFixedViewVolume.generated.h"
  11.  
  12. UCLASS()
  13. class DEMO_API ABaseSceneFixedViewVolume : public AActor
  14. {
  15. GENERATED_BODY()
  16.  
  17. public:
  18. // Sets default values for this actor's properties
  19. ABaseSceneFixedViewVolume();
  20.  
  21. // Called when the game starts or when spawned
  22. virtual void BeginPlay() override;
  23.  
  24. // Called every frame
  25. virtual void Tick( float DeltaSeconds ) override;
  26.  
  27. FVector Lcation;
  28. FRotator Rotator;
  29.  
  30. UPROPERTY(EditDefaultsOnly, Category = "SceneFixedView", meta = (AllowPrivateAccess = "true"))
  31. UBoxComponent* Triggers;
  32.  
  33. UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "SceneFixedView", meta = (AllowPrivateAccess = "true"))
  34. UCameraComponent* Camera;
  35.  
  36. UFUNCTION()
  37. virtual void OnBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweeoResult);
  38.  
  39. UFUNCTION()
  40. virtual void OnEndOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
  41.  
  42. UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "SceneFixedView")
  43. bool bCalView=false;
  44.  
  45. UPROPERTY(EditDefaultsOnly,Category="SceneFixedView")
  46. FVector VolumeSize = FVector(, , );
  47.  
  48. ADemoCharacter* Character;
  49.  
  50. ADemoCameraManager* CameraManage;
  51.  
  52. FName OriginMode;
  53. };
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #include "Demo.h"
  4. #include "BaseSceneFixedViewVolume.h"
  5.  
  6. // Sets default values
  7. ABaseSceneFixedViewVolume::ABaseSceneFixedViewVolume()
  8. {
  9. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  10. PrimaryActorTick.bCanEverTick = true;
  11.  
  12. Triggers = CreateDefaultSubobject<UBoxComponent>(TEXT("Triggers"));
  13. Triggers->SetBoxExtent(VolumeSize);
  14. Triggers->SetRelativeLocation(FVector(,,VolumeSize.Z/));
  15. RootComponent = Triggers;
  16.  
  17. Camera= CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
  18. Camera->SetRelativeLocation(FVector(VolumeSize.X,VolumeSize.Y,VolumeSize.Z));
  19. Camera->AttachTo(RootComponent);
  20.  
  21. //FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
  22. //FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
  23. //FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
  24.  
  25. Triggers->OnComponentBeginOverlap.AddDynamic(this, &ABaseSceneFixedViewVolume::OnBeginOverlap);
  26. Triggers->OnComponentEndOverlap.AddDynamic(this, &ABaseSceneFixedViewVolume::OnEndOverlap);
  27. }
  28.  
  29. // Called when the game starts or when spawned
  30. void ABaseSceneFixedViewVolume::BeginPlay()
  31. {
  32. Super::BeginPlay();
  33.  
  34. }
  35.  
  36. // Called every frame
  37. void ABaseSceneFixedViewVolume::Tick( float DeltaTime )
  38. {
  39. Super::Tick( DeltaTime );
  40. if (bCalView)
  41. {
  42. if (Character)
  43. {
  44. Character->ViewTargetLocation = Camera->K2_GetComponentLocation();
  45. Character->ViewTargetRotator = UKismetMathLibrary::FindLookAtRotation(Camera->K2_GetComponentLocation(), Character->GetActorLocation());
  46. }
  47. }
  48. }
  49. void ABaseSceneFixedViewVolume::OnBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweeoResult)
  50. {
  51. Character = Cast<ADemoCharacter>(OtherActor);
  52. if (Character)
  53. {
  54. bCalView = true;
  55. ADemoPlayerController* Controller = Cast<ADemoPlayerController>(Character->GetController());
  56. if (Controller)
  57. {
  58. OriginMode=Controller->PlayerCameraManager->CameraStyle;
  59. Controller->SetCameraMode(FName("SceneFixed"));
  60. //因为我使用控制类来管理视角,为了解决一些视角问题,所以在进入时,必须重新设置视角,屏蔽鼠标修改视角
  61. Controller->SetControlRotation(FRotator(0.0f,90.0f,0.0f));
  62. Controller->SetIgnoreLookInput(true);
  63. }
  64. }
  65. }
  66.  
  67. void ABaseSceneFixedViewVolume::OnEndOverlap(class AActor* OtherActor ,class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
  68. {
  69. if (OtherActor==Character)
  70. {
  71. bCalView = false;
  72. ADemoPlayerController* Controller = Cast<ADemoPlayerController>(Character->GetController());
  73. if (Controller)
  74. {
  75. if (OriginMode!=FName(""))
  76. {
  77. Controller->SetCameraMode(OriginMode);
  78. }
  79. else
  80. {
  81. Controller->SetCameraMode(FName("Default"));
  82. }
  83. Controller->SetIgnoreLookInput(false);
  84. }
  85. }
  86. Character= nullptr;
  87. }

关于如何通过定义自己的CameraManager来控制视角的更多相关文章

  1. struts自己定义拦截器--登录权限控制

    说明:该自己定义的拦截器实现用户登录的权限控制. login.jsp--->LoginAction--重定向-->MainAction--->main.jsp 一.1.整体的步骤: ...

  2. VC中预处理指令与宏定义详解

    刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...

  3. C 宏定义

    C/C++中宏使用总结 .C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释 ...

  4. linux C宏定义 转

    写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等.下面列举一些成熟软件中常用得宏定义...... 1,防止一个头文件被重复包含 #ifndef COMDEF_H ...

  5. c c++面试c工程开发之宏定义和条件编译

    多数c语言的初学者对c工程开发过程各个阶段的作用理解不到位,而这方面的的知识又是实际开发过程中经常用到的技能点,所以就成为面试考察中一个重要的考察方面.例如:头文件的作用.头文件的内容:链接的作用和意 ...

  6. 交换机VLAN的定义、意义以及划分方式

    什么是VLAN 虚拟网技术(VLAN,Virtual Local Area Network)的诞生主要源于广播.广播在网络中起着非常重要的作用,如发现新设备.调整网络路径.IP地址租赁等等,许多网络协 ...

  7. C语言预处理命令总结大全 :宏定义

    C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性.ANS ...

  8. Java中常见方法详解合集(方法的定义及语法结构)

    Java的方法定义 1.方法的定义 方法是控制对象的动作行为方式与准则,在Java中方法位于类体下又有另一种含义. 普通的方法在类中称为"实例方法",因为方法的调用需要创建对象,而 ...

  9. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

随机推荐

  1. ecshop后台 计划任务

    计划任务定时清理掉设置后的内容 主要针对单表删除(日志,):对于多表删除,不太好用(订单+订单商品+订单日志) 结构: 1.计划任务语言包:languages\zh_cn\cron\ 2.php文件: ...

  2. memcached的key,value,过期时间的限制

    1.   key值最大长度? memcached的key的最大长度是250个字符,是memcached服务端的限制. 如果您使用的客户端支持"key的前缀"或类似特性,那么key( ...

  3. php提供更快的文件下载

    在微博上偶然看到一篇介绍php更快下载文件的方法,其实就是利用web服务器的xsendfile特性,鸟哥的博客中只说了apache的实现方式,我找到了介绍nginx实现方式的文章,整理一下! let' ...

  4. github提交代码时,报permission denied publickey

    在像github提交代码时,报permission denied publickey. 查找了一下,可能是因为github的key失效了. 按照以下步骤,重新生成key. ssh-keygen 一路默 ...

  5. Rails的三种环境----开发环境,生产环境和测试环境

    Rails 的三个环境 Rails 的应用程序预设提供了三种不同的执行模式: development environment 开发模式,用在你的开发的时候 test environment 测试模式, ...

  6. 【阿里李战】解剖JavaScript中的 null 和 undefined

    在JavaScript开发中,被人问到:null与undefined到底有啥区别? 一时间不好回答,特别是undefined,因为这涉及到undefined的实现原理.于是,细想之后,写下本文,请各位 ...

  7. python解析git log后生成页面显示git更新日志信息

    使用git log可以查到git上项目的更新日志. 如下两个git项目,我想把git的日志信息解析成一个便于在浏览器上查看的页面. https://github.com/gityf/lua https ...

  8. iOS抓包利器Charles

    iOS抓包利器Charles http://wonderffee.github.io/blog/2013/07/13/best-packet-capture-tool-charles-in-ios/ ...

  9. 安装第三方模块方法和requests

    如何安装第三方模块 pip3         pip3 install xxxx          源码         下载,解压         进入目录 python setup.py inst ...

  10. 文本框value联动修改

    <input id="ipt-edit" value="" /><input id="ipt-target" value= ...