C++ Programming Tutorials_2翻译



所在原文目录结构位置:

C++ Programming Guide

 |_____Programming Quick Start Guide

 |_____Introduction to C++ Programming in UE4

 |_____C++ Programming Tutorials

 |_____Managing Game Code

 |_____Development Setup

 |_____Gameplay Programming

 |_____Engine Architecture

 |_____Console Manager: Console Variables in C++

 |_____Command-Line Arguments

 |_____Assertions

 |_____Blueprint Function Libraries

 |_____Unreal Build System

 |_____Plugins

 |_____Coding Standard

 |_____Symbol Debugger


原文地址:Programming Tutorials


-------------------------------------------------------------------------------------------------------------------------------------------------------


C++ Programming Tutorials

C++编程教程


1.Player Input and Pawns 玩家输入和Pawn(个人感觉Pawn是副角色,配角) 

 见译文:  C++ Programming Tutorials_1 

2.Game-Controlled Cameras 游戏控制摄像机

This tutorial will show you how to activate a camera, and change your active camera from one to another.

本教程将展示如何激活一个摄像机,还有,切换活动的摄像机


Steps 步骤:

    1.Place Cameras In The World 在世界中放置摄像机们

          !!!If you are new to Unreal Engine 4, you might want to read ourProgramming Quick Start tutorial first. For this tutorial, we will assume you are familiar with creating a project, adding C++ code to it, compiling your code, and adding Components to Actors in the Unreal Engine editor.

           !!!如果是新手,请先看前面的译文.

           ①We will begin by creating a new Basic Code project, with starter content, named "HowTo_AutoCamera". The first thing we'll need to do is create two cameras in our world. Since there are multiple ways to set up cameras, we'll go with the two most common ways here. For our first camera, go to the Modes tab in the Placement Browser and click Place, or press Shift-1. In the All Classes section, you'll find a Camera actor. Drag this into the Level Editor and position it so that it has a good view of our scene.

              我们从创建一个新的 C++基础代码项目 开始,项目命名为"HowTo_AutoCamera". 首先,我们要在世界中创建两个摄像机.有多种方式创建摄像机们,我们这儿用两种常见的方式来创建.第一个摄像机,找到Placement Browser(布局浏览器) 下的Modes(模式)标签,点击放置,或者按Shift-1(不知道Shift-1是什么). 在All Classes (所有类)部分,你会找到Camera(相机)


       When this is done, the Level Editor window will have a picture-in-picture view of what our new Camera Actor can see as long as we have the Camera Actor selected.

        做到这儿,关卡编辑器窗口会有摄像机对象看到的画中画

       ②For our second camera, we'll use a method that goes a little more in-depth and gives us a little more control. Start by clicking on Basic in the Mode tab in the Placement Browser and dragging a Cube into the Level Editor window.

         至于我们第二个摄像机, 我们将使用一个更深入的方法,给我们更多的控制,找到Placement Browser (放置浏览器),找到Modes标签下Basic(基本)中的Cube(方块),把方块拖进关卡编辑器窗口中

 

            !!!We can use almost any actor class for this step. The MyActor class we created in the QuickStart tutorial might be interesting to substitute for the Cube.

            !!!这一步我们能用绝大多数的actor类.在QuickStart 教程中我们创建的MyActor 类是对这个Cube的替代品

           ③When our Cube actor is placed, we should add a CameraComponent to it, and set the position and rotation of that CameraComponent to give us a different view of the scene than the CameraActor we placed earlier.

           当我们的Cube对象放置好,我们需要为它增加一个CameraComponent (相机组件),设置位置和旋转以便相机组件给我们不同于原先的画面.

          ④We should customize our CameraComponent by turning on Constrain Aspect Ratio so that it matches the setting on our CameraActor. This will make transitions between camera views smoother, but it is not required.

           我们需要打开限制长宽比来设定我们的相机组件,这样它与我们的CameraActor相匹配.这将使相机视图之间流畅的过渡,但这不是必需的

           设置比率


        With our world set up, we're now ready to create the class that will control our camera view.

        我们创建好了世界,我们现在已经能创建类来控制我们的摄像机了.


     2.Control Camera View In C++ 在C++中控制摄像机的视角

            ①We're ready to create a C++ class to control our camera view. For this tutorial, we can extend Actor into a new class which we'll call CameraDirector.

              创建类控制相机,本教程,我们可以扩展Actor 到一个新的类,我们叫CameraDirector。

             ②InCameraDirector.h, add the following code to the bottom of the ACameraDirector class definition:

                在CameraDirector.h中,在ACameraDirector类定义的最后,添加如下代码:

UPROPERTY(EditAnywhere)
AActor* CameraOne;

UPROPERTY(EditAnywhere)
AActor* CameraTwo;

float TimeToNextCameraChange;


       !!!The UPROPERTY macro makes our variables visible to Unreal Engine. This way, values set in these variables will not be reset when we launch the game or reload our level or project in a future work session. We have also added the EditAnywhere keyword, which will allow us to set CameraOne and CameraTwo in the Unreal Editor.

       !!!UPROPERTY 宏让变量在虚幻中可见,通过这种方式,这些设置的变量当我们以后启动游戏,重装载关卡也不会被重置,我们也加了EditAnywhere 这个关键字,这允许了虚幻编辑器能对该两个变量做修改了.

       ③In CameraDirector.cpp, add the following line of code to the top of the file, right underneath the other "#include" lines:

        在CameraDirector.cpp中,添加如下头文件

     

#include "Kismet/GameplayStatics.h"


       The GameplayStatics header file gives us access to some useful general-purpose functions, one of which we will need for this tutorial. When that is done, add the following code to the bottom of ACameraDirector::Tick:

       这个头文件给了我们一些有用的通用函数,其中一个我们本教程需要,这步做完,在ACameraDirector::Tick底部添加如下代码:


const float TimeBetweenCameraChanges = 2.0f;
const float SmoothBlendTime = 0.75f;
TimeToNextCameraChange -= DeltaTime;
if (TimeToNextCameraChange <= 0.0f)
{
    TimeToNextCameraChange += TimeBetweenCameraChanges;

    // Find the actor that handles control for the local player.
    APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
    if (OurPlayerController)
    {
        if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
        {
            // Cut instantly to camera one.
            OurPlayerController->SetViewTarget(CameraOne);
        }
        else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
        {
            // Blend smoothly to camera two.
            OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
        }
    }
}

This code will cause us to switch the default player's view between two different cameras every three seconds.

这段代码将使我们每三秒在两个摄像机之间切换


完整代码:

CameraDirector.h

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

#pragma once

#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"

UCLASS()
class HOWTO_AUTOCAMERA_API ACameraDirector : public AActor
{
    GENERATED_BODY()

public: 
    // Sets default values for this actor's properties
    ACameraDirector();

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

    // Called every frame
    virtual void Tick( float DeltaSeconds ) override;

    UPROPERTY(EditAnywhere)
    AActor* CameraOne;

    UPROPERTY(EditAnywhere)
    AActor* CameraTwo;

    float TimeToNextCameraChange;
};

CameraDirector.cpp

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

#include "HowTo_AutoCamera.h"
#include "CameraDirector.h"
#include "Kismet/GameplayStatics.h"//里面有一些有用的通用函数

// Sets default values
ACameraDirector::ACameraDirector()
{
    // 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;

}

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

}

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

    const float TimeBetweenCameraChanges = 2.0f;
    const float SmoothBlendTime = 0.75f;
    TimeToNextCameraChange -= DeltaTime;
    if (TimeToNextCameraChange <= 0.0f)
    {
        TimeToNextCameraChange += TimeBetweenCameraChanges;

        //Find the actor that handles control for the local player.//找到这个actor
        APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
        if (OurPlayerController)
        {
            if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
            {
                //Cut instantly to camera one.//直接切换到相机1
                OurPlayerController->SetViewTarget(CameraOne);
            }
            else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
            {
                //Blend smoothly to camera two.//平滑地切换到相机2
                OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
            }
        }
    }
}


    3. Place A Camera Director In The World  在世界中放置一个主导摄像机

           ①Once our code has compiled, we can drag an instance of our new class from the Content Browser into the Level Editor.

            编译好代码后,我们把CameraDirector拖进游戏关卡中,这就创建了一个实例了

               ②Next, we'll need to set the CameraOne and CameraTwo variables. Find our CameraDirector in the World Outliner and edit it in the Details Panel.

                下面,我们需要设置CameraOne 和CameraTwo 这两个变量.在World Outliner (世界大纲视图)中找到我们的实例,然后编辑:

然后编辑


          ③If we press Play, we will see the camera snap to this view:

           按Play,观察效果图:


We now have a system that moves the player's camera based purely on game logic. This code can be modified for use in any game where the player does not have direct control over the camera, or where blending between camera views is useful.

现在我们有一个基于游戏逻辑控制玩家摄像机移动切换的系统了,这些代码能被修改用于一些玩家没有直接控制相机的游戏,或者对混合摄像机视图方面非常有用的.


     4.On Your Own! 你自己做!

Using what you have learned, try to do the following:

学以致用,做下面的事情.

  • Attach a Camera to a moving Actor to create a crane or dolly shot.

  • 为运动的对象添加摄像头,从而创建一个吊杆或移动摄影车

  • Use a single array variable to store your cameras, instead of CameraOne and CameraTwo, so you can go through a sequence of any number of cameras, instead of just two.

  • 用一个数组保存你的摄像机们,而不是相机1,相机2,因此你能遍历摄像机们的序列表,而不是仅仅两个.

  • Instead of using Actor pointers to store your cameras, create a structure that holds the pointer, as well as time before changing the view, and blend time to the new view.

  • 用保存Actor的指针和改变之前的时间 和混合时间的结构体,而不用Actor指针来保存你的相机们

As for the specifics covered in this tutorial:

本节教程的详细介绍:

//以下代码为本人的作业,仅供参考

      --------------------------------解决第一个: 运动的摄像头的问题--------------------------------

步骤:1.打开player类 ,添加

            UPROPERTY(EditAnywhere)
            AActor* CameraOne;

         2.UE编辑器中,绑定动态物体到CameraOne

         3.在Tick每帧更新这个函数中,设置CameraOne为主相机:


//获取此player
APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (OurPlayerController)
{
	if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
	{
		// 设置CameraOne为主相机
		OurPlayerController->SetViewTarget(CameraOne);
	}
}

--------------------------------解决第二个: 数组保存相机们的问题--------------------------------

用数组代替上面的.

然后就可以添加任意多个相机了.

当然,程序中CameraOne  要用下标的形式访问,变成m_Cameras[0];CameraTwo变成m_Cameras[1]

(数组下标从0开始)


--------------------------------解决第三个: 用结构体保存数据的问题--------------------------------

解:定义一个结构体嘛,谁不会.但是我为什么三天都做不出来呢???

定义的结构体如图所示:

好,分分钟定义好结构体,可是,我擦咧,怎么编译不过?

因为本人习惯看错误列表,所以,我看到的是这样的:

为了解决这个问题,我拜访了很多群,亲口尝过百草,未能解决,后来三巫社区的三叔找到了问题的本质.

修改了下,注意看好:

struct CameraAndTime
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category = "Myct")
	AActor*	camera;		//摄像机
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Myct")
	float	showTime;	//摄像机显示的时间
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Myct")
	float	blendTime;	//相机混合的时间
};

这样就编译不过!!!


struct FCameraAndTime
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category = "Myct")
	AActor*	camera;		//摄像机
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Myct")
	float	showTime;	//摄像机显示的时间
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Myct")
	float	blendTime;	//相机混合的时间
};

这样就编译过了!!!

看到上面两段代码的区别没?(坑爹啊...注意结构名!!!)

UE4连名字都不让随便取,这不是武则天么?下面是UE4家族的姓.

(都不好意思说这个问题坑了我三天了...)

好了,结构体定义完了,在里面添加

class HOWTO_AUTOCAMERA_API ACameraDirector : public AActor
{
 GENERATED_BODY()

UPROPERTY(EditAnywhere, Category = "My")
 TArray<FCameraAndTime> CameraTimes;

 int CameraIndex; //相机索引
 float ShowTimeAdd; //显示了多少时间?

}

在构造函数中,CameraIndex = 0;//从第一个相机开始

ShowTimeAdd = 0.0f;//显示的时间累加

我们的目的就是:每个摄像机显示自己的showTime时间后,花blendTime时间切换到下一个摄像机,如此循环

那么,在循环函数Tick中添加如下代码:

void ACameraDirector::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	//获取player
	APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);

	if (CameraTimes[CameraIndex].camera != NULL)//如果相机不为空
	{
		if (ShowTimeAdd >= CameraTimes[CameraIndex].showTime)//如果显示的时间到了 该相机要显示的时间
		{
			CameraIndex++;//切换到下一个(相机)
			if (CameraIndex >= CameraTimes.Num())//如果已经是最后一个相机
				CameraIndex = 0;				 //切换到第一个相机

			if (CameraTimes[CameraIndex].camera != NULL)//如果相机不为空
			{
				OurPlayerController->SetViewTargetWithBlend(CameraTimes[CameraIndex].camera, CameraTimes[CameraIndex].blendTime);//切换活动的相机
				ShowTimeAdd = 0.0f;//时间清0
			}
			else                                        //相机为空 
			{
				CameraIndex++;
				if (CameraIndex >= CameraTimes.Num())
					CameraIndex = 0;

				ShowTimeAdd = 0.0f;
			}		
		}
		else 
		{
			ShowTimeAdd += DeltaTime;//累加时间
		}
	}
	else    //相机为空
	{
		CameraIndex++; //下一个(相机)
		if (CameraIndex >= CameraTimes.Num())//如果已经是最后一个相机
			CameraIndex = 0;				 //切换到第一个相机

		ShowTimeAdd = 0.0f;//混合时间清0
	}
}

编译,在UE4里面添加三个摄像机指定好Camera,设定好时间

第一个参数:摄像机

第二个参数:摄像机显示多少秒后切换

第三个参数:需要多少时间来平滑过度切换

好了,最终效果就会在摄像机之间一直切换镜头了.

-------------------------------------------------------------------------------------------------------------------

3.Variables, Timers, and Events 变量,定时器和事件

4.Player-Controlled Cameras 玩家控制摄像机

5.Components And Collision 组件和碰撞



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章