Sorry for spending a little time playing a popular game recently. I’m sorry for the slow update, but it’s really fun. I don’t like the grand narrative, but it has a great sense of exploration and great art.

Play time, please witness.

Anyway, at least the fox tutorial is done (

1. The Class called

First create an eagle using the same logic you used to create a frog.

1.1 Explosion Effect

We want enemies to play this animation before they are destroyed, leaving aside the explosion effects. Let’s focus on what we did later in the Animator. Set a trigger variable in the Animator instead of the bool variable you’ve been using.

1.1.1 the trigger

Trigger differs from bool in that when trigger is triggered, it immediately returns to false.

1.1.2 Changing enemy status in Player

Our code for destroying enemies is in the Player script. But it’s not the player animation we’re going to change, it’s the Frog animation. So you need to get the animator.

Of course, since the information about the collider is already given in the collider, it can passcollision.gameObject.GetComponent<Animator>()But let’s change the way we think about it and put the logic of death in Enemy instead of Player. The method is to write a public function in frog and call it in player. But if you write it this way, you get this:The IDE will report an error because the other side does not have the Die method. So you should get frog.And, in Frog, you can’t link destroy immediately after the animation because you have to wait for the animation to finish playing. So Destroy uses the event to be called after the animation has played, which we’ve covered before.

1.2 inheritance

You can’t write a destroy function for every enemy class. So we created an Enemy class to reuse these features. Here’s where the code comes in:

  1. Add the Animator variable to Enemy and assign it to Start. All protected because these two property methods are called in the subclass. Where Start is the same name as virtual for override.

EnemyFrog class = ‘monoBehaviour’; EnemyFrog class = ‘EnemyFrog’; EnemyFrog class = ‘EnemyFrog’; EnemyFrog class = ‘EnemyFrog’; EnemyFrog class = ‘EnemyFrog’; EnemyFrog class = ‘EnemyFrog’; Because ‘Start’ in Enemy won’t be called without calling it.3. Do the same to EnemyEagle.

2. The audio sound

If you open the Main Camera, you’ll see that it already has an Audio Listener component. This is for collecting sound.

Generally, audio is divided into listener and source. The Listener is automatically integrated into the Main Camera. Then place various audio sources in the game for the listener to listen to.

2.1 Characters come with BGM

To bind the player to a ready-to-play BGM, add an Audio Source component to the player and drag the BGM into the Audio Clip property.

2.2 Elimination sound

Add a kill sound to the enemy. Add a sound effect first, then remove play on Awake and loop because you only want it to play when there is an explosion. Then get the AudioSource component in your code and call the Play method.

2.2.1 Renaming shortcut Keys

CTRL + R (twice) to batch rename the current variable. The advantage over CTRL + F is that it automatically determines if it is the same variable (a strongly typed language, after all).

2.3 Sound of injury and picking up

How does GetComponent separate if you add multiple sounds? The way to do this is to use public variables instead, so you can just drag the component outside.

B: Yes

Write by panel, most of which I have learned in basic courses before, and see the effect directly:

The general process is as follows:

  1. Create a new panel, add text, modify the font.
  2. Use setActive in script to make panel appear and disappear.
  3. UI animation is created by recording.

4. Get down animation

4.1 the keys

Project Setting->Input To add a new button:

I’m not going to talk about animation. I’ll skip it.

4.2 Collision DEBUG

Sometimes we want to see colliders in real time while playing. In this case, we need to enable the Gizmos button in the upper right corner and select the object we want to view in Hierarchy.

4.3 Collision body switch

We can see that when you squat down, the collider doesn’t change. So when we squat, we disable the head bump.

4.4 Keep squatting when there is an obstacle above

If you release the squat button when we pass a relatively low place, the character will return to its standing position, as shown in the picture:



So we need to add a judgment. Here we use physics2d. OverlapCircle, which determines whether a point has a LayerMask around it. Add a point to the Player and check if there are any obstacles around the point:

5. Scenario switch

This was covered in the basics tutorial, but with a little bit of knowledge.

5.1 How Do I Introduce a GameManager

Unity replaces the script icon named GameManager with a gear. GameManager is generally used to manage scenario switches (restart, win, lose, and so on). But how do you introduce this script into other scripts?

5.1.1 public

First try a new GameManegr class:The select option tells us that there is nothing to drag into the entire project:The reason is that a script is just a script, a non-static class, not an instance. You still have to instantiate it if you want it to work. So let’s create an empty object and introduce the GameObject script:Now we can finally drag it in.

(We can actually make it a static class or a static method so we don’t have to drag it around in Unity, but we’re going to use Invoke, Invoke is not a static method, so we still have to instantiate it)

5.1.2 Objects of Multiple Scripts

Multiple scripts can be mounted on an object that belongs to multiple classes. For example with the empty object, we can add an Enemy script so that the GameManager can also be introduced as the Enemy class (of course not necessary, this is just for demonstration purposes).

5.1.3 TileMap Small gaps

Sometimes there will be gaps between the maps made by TileMap. In this case, change the x and Y values of grid cell size to 0.99 to solve the problem.

5. 2 d photosynthetic efficiency

URP wasn’t selected when the project was created, so here’s a simple light effect: Create a Material, shader instead of Sprite/DiffuseAssign that to everything in the scene, and you’ll see that everything turns black, and then you can finally add the light effect, just add some simple archy to Heirarchy, and it works like this:Sometimes the light source is not bright because the principle is still 3D lighting, go to the 3D interface to see if it is too far away from the interface, change the Z axis.

There are gaps in the illuminated background, so we need to change the cell size of the grid from 0.99 to 1. If there are any, please go to Project Setting -> Graphic and turn off the anti-aliasing.

Optimize your code

6.1 Enemy Destruction

At the end of the Destroy animation we added a trigger to Destroy enemies. But we put the trigger event some place after the last frame, we should put it with the last frame to make the animation smoother.

7. What is the name of the game

Next up is the famous but cool visuals.

7.1 Cinemachine replacement follow

The cinemachine boundary was hanging on the background, but now we’re going to move the background, so we’ll have to move it somewhere else. Create a new empty object and copy over the background Collider component and position.

7.2 code

Create a new Parallex script for reuse. Public A transform that records the location of the camera. And a rate to adjust. The final code is as follows:

When the FollowRate is 1, the background and the character move at the same time, and the background is still relative to the character. So we just give the background and medium different rates.

8. The main menu

  1. Create a new scene and add a UI Panel.
  2. If you don’t want to use images, set the background of the panel to None and set the color to a solid background.
  3. To use an image, change the background to the image we want, and then adjust the color to the feeling we want.
  4. To bind an event to a button, you must have an object that refers to a function on that object. So we add a script to the Canvas, write the function in the script, and then read the function from the object. (You can’t read the script directly, you must have an instance.)

9. Pause the menu

Not much different from the main menu, just some UI operations. But it involves pausing and volume adjustment.

9.1 pause

Pause by changing timescale:

9.2 Volume Change

With AudioMixer:

  1. Create an AudioMixer and find that the Inspecter window properties are few because they are mostly in the window-> Audio -> Audio mixer panel.
  2. As you can see, -80 is the minimum and 0 is normal volume. So let’s set the minimum and maximum values for the slider in the previous UI.
  3. So in the audio source that the player created at the time, I’m going to add the audiomixer that I just created to the output, and the Audiomixer is going to automatically create a master group, so that’s fine.
  4. We then tried to modify it in the script, but found that audioMixer could not add a component at all, so the script could not be added. One option is to expose the property that you want to adjust. In this case, we want to modify the Volume property, so right-click the Volume property to see it.

5. Then change the variable name here:6. Then we’ll write a function in our code that will be the event function for slider:SetFloat is used to set the value of a property, the first parameter being the variable we just named, and the second parameter being the value you want to assign. Here value is the parameter provided by the slider event, which is the value of the slider. 7. Be careful with the additions, there are two setMasterVolumes, which we used above. Using the above, the value is determined by the slider. If you select the following, you will be asked to fill in a fixed value, and value will be the fixed value that you have preset.

Some versions do not have the above dynamic float, so you can simply retrieve the value of the slider in the function. Sliders, after all, are just a component.

10. Handle adjustment

10.1 FixedUpdate

I mentioned earlier that FixedUpdate must be executed every once in a while, but it’s not. Imagine if your computer is literally a card, FixedUpdate can’t possibly guarantee that. It can only be guaranteed as much as possible, and if your computer freezes not often, but at certain times, then FixedUpdate will execute several times at a time to keep the number of times executed within 1s fixed. For example, it was supposed to be executed once for 0.2s, but then it suddenly got stuck for 1s, and then it immediately executed 5 fixedupdates to make up for it.

10.2 Jump handle adjustment, two-stage jump

Judge jumps by detecting contact with the ground in the same way you would with a squat.

  1. Add a ground monitor to the character.
  2. Add jumpPressed and jumpTimes in the code to read jumps in fixedUpdate in the update. The latter is for the second jump.

3. Check whether the ground layer exists around the detection point.4. FixedUpdate code tweaks to add second hop logic and isGround judgment instead of isTouchingLayer.5. Two-paragraph pulsing painting processing

10.3 Unidirectional Platform

A one-way platform is one that can jump onto a platform and ignore the obstacles while jumping. Which means you can jump right up from under the platform.

  1. Start by creating a random platform. Create starts.
  2. Check “Used by Effector” in collider
  3. Add a Platform Effector 2D. Yes, one-way platform is a built-in component that doesn’t need to be implemented manually.
  4. Use one way.

11. Sound management SoundManager

The author feels that there are too many AudioSources attached to player. Want to solve out:

  1. First, as with the GameManager, create an Object with the SoundManager script.
  2. Add an AudioSource component. We want to use only one Audio source by changing the clip of this component and then playing it.
  3. Get rid of all the audio component code.
  4. Add a method to play the BGM.

5. Then when you want to play BGM later, you only need to find gamemanager to play.

11.1 Singleton Mode

When we used gamemanager before, every time we had to import the Gamemanager object, drag it and call it. We can also set the Gamemanager or soundManager to static classes so that we don’t have to drag and drop them every time. (Invoke cannot use static class)

But in addition to static classes, there is another way to call methods without introducing them, and that is the singleton pattern. Change the code to the following:

Note the red position:

  1. We first create a static variable of type itself.
  2. Set instance equal to this in the Awake lifecycle function. Instance is the instance itself.
  3. That is, the class has a static variable that can be called outside, and the value stored in the static variable is an instantiation of itself. Therefore, methods can be called through this instance. Because instance is an instance of soundManager.

Now we can play BGM very simply, as shown below, without pre-instantiation, without public drag and drop:

We can use the same method to create the remaining Audio and even optimize the previous GameManager.

11.2 Field Optimization

We don’t want to set the clip to public because it’s too much padding, but we want to drag it outside, so we need to use SerializeField:

This way, even if it’s private, you can drag it outside, but still keep it inaccessible in other code.

11.3 BGM Simultaneous Playback

It’s not good to just put the BGM in, because only one sound can exist at the same time, and if you jump up, the BGM is gone. Therefore, the BGM should be taken out separately.

11.4 lock inspector

If the actual operation will find that every time change the audio, Insepector will change, every time point back to soundManager insepector, very troublesome. Select the lock on the top right of the Inspector.

12. build

I will not repeat the details of the basic tutorial.