unity中克隆方法_复古革命:在Unity中构建Pong克隆

unity中克隆方法

Before starting you can view the game at itch.io

开始之前,您可以在itch.io上查看游戏。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第1张图片

分析傍 (Analyzing Pong)

Pong was one of the first video games ever made and was the first successful commercial game. When Pong was first created the developers most likely struggled with the logic for the code, however, nowadays you can make a simple two player Pong with one method call, colliders, and sprites. Pong gets harder to create once the decision to make a one-player Pong is made. In this tutorial, we will create the base gameplay for Pong and break down a very simple AI alternative that still adds to gameplay value.

Pong是有史以来最早的视频游戏之一,也是第一个成功的商业游戏。 最初创建Pong时,开发人员很可能会为代码的逻辑而苦恼,但是,如今,您可以使用一个方法调用,对撞机和sprite制作一个简单的两人Pong。 一旦做出制作单人Pong的决定,Pong就会变得更加难以创建。 在本教程中,我们将为Pong创建基本的游戏玩法,并分解一个非常简单的AI替代方法,该替代方法仍会增加游戏玩法的价值。

We must ask, what are the core elements of Pong gameplay? Here is a list with the answer to that question:

我们必须问,Pong游戏的核心元素是什么? 以下是该问题的答案列表:

  1. Player Input – We want the player to be able to move their paddle up and down so that they can hit the ball.

    球员输入 -我们希望球员能够上下移动他们的球拍,以便他们能够击球。

  2. Ball Collision – When the ball hits the paddle or boundaries it can’t be allowed to lose any speed.

    撞球 –当球碰到球拍或划界时,不能让其失去任何速度。

  3. Boundary Collision – The ball has to be able to bounce off of the top and bottom part of the screen so that it doesn’t leave the play area.

    边界碰撞 –球必须能够从屏幕的顶部和底部弹起,以使其不会离开比赛区域。

  4. Enemy AI – The gameplay value of the game would be next to zero if the enemy sat on the opposite end of the screen and didn’t move.

    敌人AI-如果敌人坐在屏幕的另一端并且不移动,则游戏的游戏价值将接近零。

  5. Spawning the Ball – When the ball hits one of the boundaries behind the paddles we need it to respawn so that we can continue the game.

    产生球 –当球击中球拍背后的边界之一时,我们需要它重新产生,以便我们继续比赛。

  6. Ball to Paddle Hit Area Detection – This allows for the ball to bounce off the paddle at unique angles so that we are able to to better aim the ball when it is hit with the paddle.

    球到球拍击球区域检测 –这允许球以独特的角度从球拍弹回,这样当球被球拍击中时,我们能够更好地瞄准球。

With this list we can beginning programming the game.

使用此列表,我们可以开始对游戏进行编程。

Note that any numbers used relating to a game object’s location, rotation, scale, etc are relative and may need to be changed for your specific setup.

请注意,与游戏对象的位置,旋转,比例等有关的任何数字都是相对的,可能需要针对您的特定设置进行更改。

设置游戏 (Setting up the Game)

Now that we’ve analyzed the fundamentals of Pong we can start setting up the game. Go ahead and open Unity and create a new 2D project. Once the editor opens, set the game screen’s aspect ratio to 4:3. We are using 4:3 since this is one of the most common screen ratios and is one of the closest ratios to being a standard. Inside of the Assets pane create four folders named Scripts, Sprites, Prefabs, and Materials. These folders will be used to hold all of our game assets.

现在我们已经分析了Pong的基础知识,我们可以开始设置游戏了。 继续并打开Unity并创建一个新的2D项目。 编辑器打开后,将游戏屏幕的宽高比设置为4:3。 我们使用4:3,因为这是最常见的屏幕比例之一,也是最接近标准的屏幕比例之一。 在“ Assets窗格中,创建四个名为ScriptsSpritesPrefabsMaterials文件夹。 这些文件夹将用于保存我们所有的游戏资产。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第2张图片

Download the appropriate images for the game and add them to the Sprites folder (this can be done via drag and drop). The images we just added will be the sprites, interactive game objects, used in the game.

下载适合游戏的图像并将其添加到Sprites文件夹中(可以通过拖放操作完成)。 我们刚刚添加的图像将是游戏中使用的精灵,交互式游戏对象。

Gray circle sprite
Blue square sprite
Red square sprite

We are going to need to change the pixels per unit for the sprites so that they conform to a standard. I generally use 64 pixels per unit as this gives most sprites a crisp clean look, and keeps their relative size. You can think of pixels per unit as the density of pixels allocated in a 1×1 space in Unity’s editor.

我们将需要更改子画面的单位像素,以使其符合标准。 我通常每单位使用64个像素,因为这可以使大多数精灵具有清晰的外观,并保持其相对大小。 您可以将单位像素视为在Unity编辑器中1×1空间中分配的像素密度。

Let’s set the squares’ pixels per unit to 64 and the circle’s pixels per unit can be set to 128. We can go on and add the three images to the hierarchy pane.

让我们将正方形的单位像素设置为64,将圆形的单位像素设置为128。我们可以继续并将这三个图像添加到层次结构窗格中。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第3张图片

Now we need to give each asset a name and set their initial properties and tags. You can name the blue block “Player” and set the player’s x-position to 6 and its x-scale to .2.

现在,我们需要为每个资产命名,并设置其初始属性和标签。 您可以将蓝色块命名为“ Player”,并将播放器的x位置设置为6 ,其x比例设置为.2

We are going to need to create a tag to separate the paddle game objects from other game objects. In a broad sense, you can think of Tags as categories for game objects. Click on “Untagged” (located under the player’s name) and select “Add Tag”. Create a new tag named “Paddle”, and re-select the player game object and set its tag to Paddle.

我们将需要创建一个标签,以将桨式游戏对象与其他游戏对象分开。 从广义上讲,您可以将“ Tags视为游戏对象的类别。 单击“未标记”(位于播放器名称下方),然后选择“添加标记”。 创建一个名为“ Paddle”的新标签,然后重新选择玩家游戏对象并将其标签设置为Paddle。

Name the red block “Enemy”. Set the enemy’s x-position to -6 and its x-scale to .2. Make the enemy game object’s tag Paddle.

将红色块命名为“ Enemy”。 将敌人的x位置设置为-6并将其x比例设置为.2 。 使敌人的游戏对象的标签桨。

Name the grey circle “Ball” and go on and create a new tag named “Ball”. Make sure to set the ball game object’s tag to Ball.

将灰色圆圈命名为“ Ball”,然后继续创建一个名为“ Ball”的新标签。 确保将球类游戏对象的标签设置为Ball。

添加玩家输入 (Adding Player Input)

In the Assets pane, open the Scripts folder and create a new C# script named “PlayerController”. Open the PlayerController script in your IDE and type:

在“资产”窗格中,打开“脚本”文件夹并创建一个名为“ PlayerController”的新C#脚本。 在IDE中打开PlayerController脚本,然后键入:

//speed of player
	public float speed = 10;

	//bounds of player
	public float topBound = 4.5F;
	public float bottomBound = -4.5F;

	// Use this for initialization
	void Start () {
		Time.timeScale = 0;
	}

	void Update(){

		//pauses or plays game when player hits p
		if(Input.GetKeyDown(KeyCode.P) && Time.timeScale == 0){
			Time.timeScale = 1;
		} else if(Input.GetKeyDown(KeyCode.P) && Time.timeScale == 1){
			Time.timeScale = 0;
		}
	}

	// Update is called once per frame
	void FixedUpdate () {

		//get player input and set speed
		float movementSpeedY = speed * Input.GetAxis("Vertical") * Time.deltaTime;
		transform.Translate(0, movementSpeedY, 0);

		//set bounds of player
		if(transform.position.y > topBound){
			transform.position = new Vector3(transform.position.x, topBound, 0);
		} else if(transform.position.y < bottomBound){
			transform.position = new Vector3(transform.position.x, bottomBound, 0);
		}
	}

Add the PlayerController script to the Player game object in the hierarchy pane by dragging the script onto the game object. Select the Player game object and add a Box Collider 2D to the game object by clicking on “Add Component” at the bottom of the Inspector pane.

通过将脚本拖动到游戏对象上,将PlayerController脚本添加到层次结构窗格中的Player游戏对象。 选择“玩家”游戏对象,然后单击“检查器”窗格底部的“添加组件”,将Box Collider 2D添加到游戏对象中。

撞球 (Ball Collision)

Open the Materials folder inside of the Assets pane. You can create a new Physics2D Material by right-clicking and selecting Create -> Physics2D Material (as in image below).

打开“资源”窗格内部的“材料”文件夹。 您可以通过右键单击并选择创建-> Physics2D材质来创建新的Physics2D材质(如下图所示)。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第4张图片

Go ahead and name the new material “Bounce”, and set its bounciness to 1 and its friction to 0.

继续,将新材质命名为“ Bounce”,并将其“反弹”设置为1,将其“摩擦”设置为0。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第5张图片

Select the Ball game object in the hierarchy pane. Add a Circle Collider 2D to the Ball game object. Drag the bounce material to the collider’s Material property in order to set the material to bounce. By giving the Ball game object the bounce material we make it so that when the Ball game object hits the boundaries it won’t lose any speed and will bounce off in the correct angle. We also need to add a Rigidbody 2D to the Ball game object and set gravity scale to 0, then check fixed angle.

在层次结构窗格中选择Ball游戏对象。 将Circle Collider 2D添加到Ball游戏对象。 将弹跳材质拖动到对撞机的“材质”属性,以设置要弹跳的材质。 通过为Ball游戏对象提供弹跳材料,我们可以制作它,以便当Ball游戏对象碰到边界时,它不会失去任何速度,并且会以正确的角度弹起。 我们还需要向球游戏对象添加一个刚体2D并将重力比例设置为0,然后检查固定角度。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第6张图片

Open the Scripts folder inside of the Assets pane and create a script named “BallController”. Open the BallController script inside of your IDE and type:

打开“资产”窗格内部的“脚本”文件夹,然后创建一个名为“ BallController”的脚本。 打开IDE内的BallController脚本,然后键入:

//speed of the ball
	public float speed = 3.5F;

	//the initial direction of the ball
	private Vector2 spawnDir;

	//ball's components
	Rigidbody2D rig2D;
	// Use this for initialization
	void Start () {
		//setting balls Rigidbody 2D
		rig2D = this.gameObject.GetComponent();

		//generating random number based on possible initial directions
		int rand = Random.Range(1,4);

		//setting initial direction
		if(rand == 1){
			spawnDir = new Vector2(1,1);
		} else if(rand == 2){
			spawnDir = new Vector2(1,-1);
		} else if(rand == 3){
			spawnDir = new Vector2(-1,-1);
		} else if(rand == 4){
			spawnDir = new Vector2(-1,1);
		}

		//moving ball in initial direction and adding speed
		rig2D.velocity = (spawnDir*speed);

	}

边界碰撞 (Boundary Collision)

Inside of the hierarchy pane, create two empty game objects (right-click -> create empty), and name the new game objects “RightBound” and “TopBound”. Set the RightBound’s x-position to 7 and add a Box Collider 2D to the RightBound game object. In the Inspector pane check “Is Trigger” and set the collider’s y-size to 20. Duplicate the RightBound game object (select it and Command+D). Name the duplicate “LeftBound” and set its y-position to -7.

在层次结构窗格中,创建两个空的游戏对象(右键单击->创建空白),然后将新游戏对象命名为“ RightBound”和“ TopBound”。 将RightBound的x位置设置为7,并将Box Collider 2D添加到RightBound游戏对象。 在“检查器”窗格中,选中“是触发器”,并将对撞机的y大小设置为20。复制RightBound游戏对象(选择它并按Command + D)。 将重复项命名为“ LeftBound”,并将其y位置设置为-7。

Next, select the TopBound game object and set its y-position to 5.5, and add a Box Collider 2D to the TopBound game object. Set the collider’s x-size to 20. Duplicate the TopBound game object and name the duplicate “BottomBound”. Set the BottomBound game object’s y-position to -5.5.

接下来,选择TopBound游戏对象并将其y位置设置为5.5,然后将Box Collider 2D添加到TopBound游戏对象。 将对撞机的x大小设置为20。复制TopBound游戏对象,并将重复的对象命名为“ BottomBound”。 将BottomBound游戏对象的y位置设置为-5.5。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第7张图片

We want the left and right bounds to destroy the ball when the ball gets past one of the paddles. Inside of the Assets pane open the Scripts folder and create a new C# script named “BoundController”. Open BoundController inside of your favorite IDE and type:

我们希望当球越过桨之一时,左右边界破坏球。 在“资产”窗格中,打开“脚本”文件夹,然后创建一个名为“ BoundController”的新C#脚本。 在您喜欢的IDE中打开BoundController并输入:

void OnTriggerEnter2D(Collider2D other){

		//Destroys gameobject if its tag is Ball
		if(other.gameObject.tag == "Ball"){
			Destroy(other.gameObject);
		}
}

Add the BoundController script to the LeftBound game object and the RightBound game object.

将BoundController脚本添加到LeftBound游戏对象和RightBound游戏对象。

敌人AI (Enemy AI)

Select the Enemy game object and add a Box Collider 2D. Inside of the Assets pane open the Scripts folder. Create a new C# script named “EnemyController” and type:

选择“敌人”游戏对象并添加Box Collider 2D。 在“资产”窗格中,打开“脚本”文件夹。 创建一个名为“ EnemyController”的新C#脚本,然后键入:

//Speed of the enemy
	public float speed = 1.75F;

	//the ball
	Transform ball;

	//the ball's rigidbody 2D
	Rigidbody2D ballRig2D;

	//bounds of enemy
	public float topBound = 4.5F;
	public float bottomBound = -4.5F;

	// Use this for initialization
	void Start () {

	}

	// Update is called once per frame
	void FixedUpdate () {

		//finding the ball
		ball = GameObject.FindGameObjectWithTag("Ball").transform;

		//setting the ball's rigidbody to a variable
		ballRig2D = ball.GetComponent();

		//checking x direction of the ball
		if(ballRig2D.velocity.x < 0){

			//checking y direction of ball
			if(ball.position.y < this.transform.position.y){
				//move ball down if lower than paddle
				transform.Translate(Vector3.down*speed*Time.deltaTime);
			} else if(ball.position.y > this.transform.position.y){
				//move ball up if higher than paddle
				transform.Translate(Vector3.up*speed*Time.deltaTime);
			}

		}

		//set bounds of enemy
		if(transform.position.y > topBound){
			transform.position = new Vector3(transform.position.x, topBound, 0);
		} else if(transform.position.y < bottomBound){
			transform.position = new Vector3(transform.position.x, bottomBound, 0);
		}
	}

Note: 1.75 is used for the enemy’s speed solely because it makes the enemy slow enough not to be able to get to every ball that comes its direction.

注意:1.75用于敌人的速度仅仅是因为它使敌人足够慢,以至于无法到达其方向的每个球。

Another Note: We used fixed update because this method is better for movement since it updates the game object at a fixed rate.

另一个注意事项:我们使用固定更新,因为此方法更适合移动,因为它以固定速率更新游戏对象。

产生球 (Spawning the Ball)

Create an empty game object inside of the hierarchy pane and name it “BallSpawner”. Next, add the Ball game object to the Prefabs folder inside of the Assets pane. We can delete the Ball game object inside of the hierarchy pane.

在层次结构窗格中创建一个空的游戏对象,并将其命名为“ BallSpawner”。 接下来,将Ball游戏对象添加到Assets窗格内的Prefabs文件夹中。 我们可以删除层次结构窗格内的Ball游戏对象。

Open the Scripts folder inside of the Assets pane and create a new C# script named “BallSpawnerController”. Open BallSpawnerController inside of your IDE and type:

打开“资产”窗格内部的“脚本”文件夹,然后创建一个名为“ BallSpawnerController”的新C#脚本。 在IDE内打开BallSpawnerController并输入:

public GameObject ball;

	// Use this for initialization
	void Start () {
		GameObject ballClone;
		ballClone = Instantiate(ball, this.transform.position, this.transform.rotation) as GameObject;
		ballClone.transform.SetParent(this.transform);
	}

	// Update is called once per frame
	void Update () {
		if(transform.childCount == 0){
			GameObject ballClone;
			ballClone = Instantiate(ball, this.transform.position, this.transform.rotation) as GameObject;
			ballClone.transform.SetParent(this.transform);
		}
	}

Add the BallSpawnerController script to the BallSpawner game object. Now we can drag the Ball game object from the Prefabs folder into the Ball value of the BallSpawnerController.

将BallSpawnerController脚本添加到BallSpawner游戏对象。 现在,我们可以将Ball游戏对象从Prefabs文件夹拖到BallSpawnerController的Ball值中。

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第8张图片

添加基本​​文字 (Adding Basic Text)

We need to add some text to the screen telling players to hit P to play and pause the game so that players know how to start and pause the game.

我们需要在屏幕上添加一些文本,告诉玩家按下P来玩和暂停游戏,以便玩家知道如何开始和暂停游戏。

We can create a text game object (in the hierarchy pane right-click -> UI -> Text), and name the text game object PlayText. Next let’s set its Text value to “Hit P to play or pause” and center align the text. Now we can align the game object to the top of the screen and then anchor it. Let’s set its width to 200 so that all of the text is visible. Finally, set the text color to white.

我们可以创建一个文本游戏对象(在层次结构窗格中,右键单击-> UI-> Text),并命名该文本游戏对象PlayText。 接下来,将其“文本”值设置为“命中P以播放或暂停”,并使文本居中对齐。 现在,我们可以将游戏对象对准屏幕顶部,然后将其锚定。 让我们将其宽度设置为200,以便所有文本都可见。 最后,将文本颜色设置为白色。

Save the scene and add it to the build settings (by dragging or checking add current scene) and you’re done!

保存场景并将其添加到构建设置中(通过拖动或选中添加当前场景),您就完成了!

unity中克隆方法_复古革命:在Unity中构建Pong克隆_第9张图片

结论 (Conclusion)

You have now officially created a basic one-player Pong clone in Unity2D. For more practice try to think of ways to update the game and make it better – add accelleration to the ball (the more hits, the faster the ball), add inertia to paddles, add difficulty levels by increasing the enemy speed, etc.

您现在已经在Unity2D中正式创建了一个基本的单人Pong克隆。 要进行更多练习,请尝试思考更新游戏并使其变得更好的方法–向球中添加加速度(击球次数越多,球越快),向桨叶添加惯性,通过提高敌人速度来增加难度,等等。

You can download the project on GitHub

您可以在GitHub上下载项目

翻译自: https://www.sitepoint.com/retro-revolution-building-a-pong-clone-in-unity/

unity中克隆方法

你可能感兴趣的:(游戏,python,unity,游戏开发,unity3d)