Layer | Loop | Position |
Background with the sky | Yes | (0, 0, 10) |
Background (1st row of flying platforms) | No | (0, 0, 9) |
Middleground (2nd row of flying platforms) | No | (0, 0, 5) |
Foreground with players and enemies | No | (0, 0, 0) |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
using UnityEngine;
/// <summary> /// Parallax scrolling script that should be assigned to a layer /// </summary> public class ScrollingScript : MonoBehaviour { /// <summary> /// Scrolling speed /// </summary> public Vector2 speed = new Vector2( 2, 2); /// <summary> /// Moving direction /// </summary> public Vector2 direction = new Vector2(- 1, 0); /// <summary> /// Movement should be applied to camera /// </summary> public bool isLinkedToCamera = false; void Update() { // Movement Vector3 movement = new Vector3( speed.x * direction.x, speed.y * direction.y, 0); movement *= Time.deltaTime; transform.Translate(movement); // Move the camera if (isLinkedToCamera) { Camera.main.transform.Translate(movement); } } } |
Layer | Speed | Direction | Linked to Camera |
0 - Background | (1, 1) | (-1, 0, 0) | No |
1 - Background elements | (1.5, 1.5) | (-1, 0, 0) | No |
2 - Middleground | (2.5, 2.5) | (-1, 0, 0) | No |
3 - Foreground | (1, 1) | (1, 0, 0) | Yes |
1
2 3 4 5 6 7 8 9 10 |
using UnityEngine;
public static class RendererExtensions { public static bool IsVisibleFrom( this Renderer renderer, Camera camera) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera); return GeometryUtility.TestPlanesAABB(planes, renderer.bounds); } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
using System.Collections.Generic;
using System.Linq; using UnityEngine; /// <summary> /// Parallax scrolling script that should be assigned to a layer /// </summary> public class ScrollingScript : MonoBehaviour { /// <summary> /// Scrolling speed /// </summary> public Vector2 speed = new Vector2( 10, 10); /// <summary> /// Moving direction /// </summary> public Vector2 direction = new Vector2(- 1, 0); /// <summary> /// Movement should be applied to camera /// </summary> public bool isLinkedToCamera = false; /// <summary> /// 1 - Background is infinite /// </summary> public bool isLooping = false; /// <summary> /// 2 - List of children with a renderer. /// </summary> private List<Transform> backgroundPart; // 3 - Get all the children void Start() { // For infinite background only if (isLooping) { // Get all the children of the layer with a renderer backgroundPart = new List<Transform>(); for ( int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); // Add only the visible children if (child.renderer != null) { backgroundPart.Add(child); } } // Sort by position. // Note: Get the children from left to right. // We would need to add a few conditions to handle // all the possible scrolling directions. backgroundPart = backgroundPart.OrderBy( t => t.position.x ).ToList(); } } void Update() { // Movement Vector3 movement = new Vector3( speed.x * direction.x, speed.y * direction.y, 0); movement *= Time.deltaTime; transform.Translate(movement); // Move the camera if (isLinkedToCamera) { Camera.main.transform.Translate(movement); } // 4 - Loop if (isLooping) { // Get the first object. // The list is ordered from left (x position) to right. Transform firstChild = backgroundPart.FirstOrDefault(); if (firstChild != null) { // Check if the child is already (partly) before the camera. // We test the position first because the IsVisibleFrom // method is a bit heavier to execute. if (firstChild.position.x < Camera.main.transform.position.x) { // If the child is already on the left of the camera, // we test if it's completely outside and needs to be // recycled. if (firstChild.renderer.IsVisibleFrom(Camera.main) == false) { // Get the last child position. Transform lastChild = backgroundPart.LastOrDefault(); Vector3 lastPosition = lastChild.transform.position; Vector3 lastSize = (lastChild.renderer.bounds.max - lastChild.renderer.bounds.min); // Set the position of the recyled one to be AFTER // the last child. // Note: Only work for horizontal scrolling currently. firstChild.position = new Vector3(lastPosition.x + lastSize.x, firstChild.position.y, firstChild.position.z); // Set the recycled child to the last position // of the backgroundPart list. backgroundPart.Remove(firstChild); backgroundPart.Add(firstChild); } } } } } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
using UnityEngine;
/// <summary> /// Enemy generic behavior /// </summary> public class EnemyScript : MonoBehaviour { private bool hasSpawn; private MoveScript moveScript; private WeaponScript[] weapons; void Awake() { // Retrieve the weapon only once weapons = GetComponentsInChildren<WeaponScript>(); // Retrieve scripts to disable when not spawn moveScript = GetComponent<MoveScript>(); } // 1 - Disable everything void Start() { hasSpawn = false; // Disable everything // -- collider collider2D.enabled = false; // -- Moving moveScript.enabled = false; // -- Shooting foreach (WeaponScript weapon in weapons) { weapon.enabled = false; } } void Update() { // 2 - Check if the enemy has spawned. if (hasSpawn == false) { if (renderer.IsVisibleFrom(Camera.main)) { Spawn(); } } else { // Auto-fire foreach (WeaponScript weapon in weapons) { if (weapon != null && weapon.enabled && weapon.CanAttack) { weapon.Attack( true); } } // 4 - Out of the camera ? Destroy the game object. if (renderer.IsVisibleFrom(Camera.main) == false) { Destroy(gameObject); } } } // 3 - Activate itself. private void Spawn() { hasSpawn = true; // Enable everything // -- Collider collider2D.enabled = true; // -- Moving moveScript.enabled = true; // -- Shooting foreach (WeaponScript weapon in weapons) { weapon.enabled = true; } } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
void Update()
{ // ... // 6 - Make sure we are not outside the camera bounds var dist = (transform.position - Camera.main.transform.position).z; var leftBorder = Camera.main.ViewportToWorldPoint( new Vector3( 0, 0, dist) ).x; var rightBorder = Camera.main.ViewportToWorldPoint( new Vector3( 1, 0, dist) ).x; var topBorder = Camera.main.ViewportToWorldPoint( new Vector3( 0, 0, dist) ).y; var bottomBorder = Camera.main.ViewportToWorldPoint( new Vector3( 0, 1, dist) ).y; transform.position = new Vector3( Mathf.Clamp(transform.position.x, leftBorder, rightBorder), Mathf.Clamp(transform.position.y, topBorder, bottomBorder), transform.position.z ); // End of the update method } |
Category | Parameter name | Value |
General | Duration | 1 |
General | Max Particles | 15 |
General | Start Lifetime | 1 |
General | Start Color | Gray |
General | Start Speed | 3 |
General | Start Size | 2 |
Emission | Bursts | 0 : 15 |
Shape | Shape | Sphere |
Color Over Lifetime | Color | See below (N°1) |
Size Over Lifetime | Size | See below (N°2) |
Category | Parameter name | Value |
General | Looping | false |
General | Duration | 1 |
General | Max Particles | 10 |
General | Start Lifetime | 1 |
General | Start Speed | 0.5 |
General | Start Size | 2 |
Emission | Bursts | 0 : 10 |
Shape | Shape | Box |
Color Over Lifetime | Color | See below (N°1) |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using UnityEngine;
/// <summary> /// Creating instance of particles from code with no effort /// </summary> public class SpecialEffectsHelper : MonoBehaviour { /// <summary> /// Singleton /// </summary> public static SpecialEffectsHelper Instance; public ParticleSystem smokeEffect; public ParticleSystem fireEffect; void Awake() { // Register the singleton if (Instance != null) { Debug.LogError( "Multiple instances of SpecialEffectsHelper!"); } Instance = this; } /// <summary> /// Create an explosion at the given location /// </summary> /// <param name="position"></param> public void Explosion(Vector3 position) { // Smoke on the water instantiate(smokeEffect, position); // Tu tu tu, tu tu tudu // Fire in the sky instantiate(fireEffect, position); } /// <summary> /// Instantiate a Particle system from prefab /// </summary> /// <param name="prefab"></param> /// <returns></returns> private ParticleSystem instantiate(ParticleSystem prefab, Vector3 position) { ParticleSystem newParticleSystem = Instantiate( prefab, position, Quaternion.identity ) as ParticleSystem; // Make sure it will be destroyed Destroy( newParticleSystem.gameObject, newParticleSystem.startLifetime ); return newParticleSystem; } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public Damage(
int damageCount)
{ // ... if (hp <= 0) { // 'Splosion! SpecialEffectsHelper.Instance.Explosion(transform.position); // Dead! Destroy(gameObject); } // ... } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
using UnityEngine;
using System.Collections; /// <summary> /// Creating instance of sounds from code with no effort /// </summary> public class SoundEffectsHelper : MonoBehaviour { /// <summary> /// Singleton /// </summary> public static SoundEffectsHelper Instance; public AudioClip explosionSound; public AudioClip playerShotSound; public AudioClip enemyShotSound; void Awake() { // Register the singleton if (Instance != null) { Debug.LogError( "Multiple instances of SoundEffectsHelper!"); } Instance = this; } public void MakeExplosionSound() { MakeSound(explosionSound); } public void MakePlayerShotSound() { MakeSound(playerShotSound); } public void MakeEnemyShotSound() { MakeSound(enemyShotSound); } /// <summary> /// Play a given sound /// </summary> /// <param name="originalClip"></param> private void MakeSound(AudioClip originalClip) { // As it is not 3D audio clip, position doesn't matter. AudioSource.PlayClipAtPoint(originalClip, transform.position); } } |
1
|
SoundEffectsHelper.Instance.MakeExplosionSound();
|
1
|
SoundEffectsHelper.Instance.MakePlayerShotSound();
|
1
|
SoundEffectsHelper.Instance.MakeEnemyShotSound();
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using UnityEngine;
/// <summary> /// Title screen script /// </summary> public class MenuScript : MonoBehaviour { void OnGUI() { const int buttonWidth = 84; const int buttonHeight = 60; // Draw a button to start the game if ( GUI.Button( // Center in X, 2/3 of the height in Y new Rect( Screen.width / 2 - (buttonWidth / 2), ( 2 * Screen.height / 3) - (buttonHeight / 2), buttonWidth, buttonHeight ), "Start!" ) ) { // On Click, load the first level. // "Stage1" is the name of the first scene we created. Application.LoadLevel( "Stage1"); } } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using UnityEngine;
/// <summary> /// Start or quit the game /// </summary> public class GameOverScript : MonoBehaviour { void OnGUI() { const int buttonWidth = 120; const int buttonHeight = 60; if ( GUI.Button( // Center in X, 1/3 of the height in Y new Rect( Screen.width / 2 - (buttonWidth / 2), ( 1 * Screen.height / 3) - (buttonHeight / 2), buttonWidth, buttonHeight ), "Retry!" ) ) { // Reload the level Application.LoadLevel( "Stage1"); } if ( GUI.Button( // Center in X, 2/3 of the height in Y new Rect( Screen.width / 2 - (buttonWidth / 2), ( 2 * Screen.height / 3) - (buttonHeight / 2), buttonWidth, buttonHeight ), "Back to menu" ) ) { // Reload the level Application.LoadLevel( "Menu"); } } } |
1
2 3 4 5 6 7 |
void OnDestroy()
{ // Game Over. // Add the script to the parent because the current game // object is likely going to be destroyed immediately. transform.parent.gameObject.AddComponent<GameOverScript>(); } |