Se avete seguito il corso sino ad ora, dovreste essere in grado di realizzare autonomamente un Prefab di un missile animato utilizzando l'immagine seguente.
Le operazioni da effettuare sono le stesse che abbiamo seguito per la realizzazione dell'animazione dell'astronave. L'unica differenza e che questa volta, al termine delle operazioni, trascineremo il missile dalla scena nella cartella Prefabs. Riassumendo in breve:
- Importiamo la texture ed effettuiamone lo splice
- Creiamo un nuovo sprite nella scena ed associamogli la texture del missile
- Creiamo una animazione utilizzando le altre due immagini così come abbiamo fatto per i motori dell'astronave
- Aggiungiamo allo sprite un Rigid Body 2D con Gravity Scale impostato a 0 e Fixed Angles selezionato
- Aggiungiamo un Box Collider 2D dimenzionandolo opportunamente
- Trasciniamo lo sprite nei Prefabs e rinominiamolo in Missile
Nel Box Collider ricordiamoci di selezionare la casella di spunta IsTrigger. Così facendo si indica al motore di fisica 2D di ignorare la gestione delle collisioni, e di chiamare generare l'evento OnTriggerEnter2D dell'oggetto colpito. Questo eviterà al nostro proiettile di rimbalzare semplicemente contro le cose, e ci consentirà di gestire l'evento da codice. Potremo quindi decidere se distruggere gli oggetti colpiti o se diminuirne il livello di energia.
Il Prefab è quasi completo. Occorre solo aggiungerci gli script per la gestione.
Il primo è uno script generico che riutilizzeremo anche per altri oggetti,e che serve a far muovere in maniera lineare le cose. Notiamo che la velocità può essere impostata tramite la proprietà Speed.
using UnityEngine; ////// Simply moves the current game object /// public class MoveScript : MonoBehaviour { // 1 - Designer variables ////// Object speed /// public Vector2 speed = new Vector2(25, 25); ////// Moving direction /// public Vector2 direction = new Vector2(-1, 0); public Vector2 hotSpot = new Vector2(1, 0); private Vector2 movement; void Update() { // 2 - Movement movement = new Vector2( speed.x * direction.x, speed.y * direction.y); } void FixedUpdate() { // Apply movement to the rigidbody rigidbody2D.velocity = movement; } }
Il secondo invece fa in modo che il missile si autodistrugga una volta fuoriuscito dalla visuale di gioco,evitando che i missili continuino il loro viaggio all'interno della scena di gioco ancora non visibile.
using UnityEngine; ////// Projectile behavior /// public class ShotScript : MonoBehaviour { // 1 - Designer variables ////// Damage inflicted /// public int damage = 1; ////// Projectile damage player or enemies? /// public bool isEnemyShot = false; void Start() { // 2 - Limited time to live to avoid any leak Destroy(gameObject, 5); } void Update() { // Limitazione della posizione del Player all'interno dei limiti dello schermo (Camera) var dist = (transform.position - Camera.main.transform.position).z; var rightBorder = Camera.main.ViewportToWorldPoint( new Vector3(1, 0, dist) ).x; if (transform.position.x > rightBorder) { Destroy(gameObject); } var leftBorder = Camera.main.ViewportToWorldPoint( new Vector3(0, 0, dist) ).x; if (transform.position.x < leftBorder) { Destroy(gameObject); } } }
Aggiungiamo questi due nuovi script al nostro Prefab Missile, che sarà quindi pronto per essere sparato.
Per poterlo fare occorre creare una istanza del Prefab all'interno della scena di gioco giusto davanti alla nostra astronave.
Creiamo quindi il seguente WeaponScript.
using UnityEngine; ////// Launch projectile /// public class WeaponScript : MonoBehaviour { //-------------------------------- // 1 - Designer variables //-------------------------------- ////// Projectile prefab for shooting /// public Transform shotPrefab; ////// Cooldown in seconds between two shots /// public float shootingRate = 0.25f; ////// The hot spot /// public Vector3 hotSpot = new Vector3(0, 0,0); //-------------------------------- // 2 - Cooldown //-------------------------------- private float shootCooldown; void Start() { shootCooldown = 0f; } void Update() { if (shootCooldown > 0) { shootCooldown -= Time.deltaTime; } } //-------------------------------- // 3 - Shooting from another script //-------------------------------- ////// Create a new projectile if possible /// public void Attack(bool isEnemy) { if (CanAttack) { shootCooldown = shootingRate; // Create a new shot var shotTransform = Instantiate(shotPrefab) as Transform; // Assign position shotTransform.position = transform.position + hotSpot ; // The is enemy property ShotScript shot = shotTransform.gameObject.GetComponent(); if (shot != null) { shot.isEnemyShot = isEnemy; } // Make the weapon shot always towards it //MoveScript move = shotTransform.gameObject.GetComponent (); //if (move != null) //{ // move.direction = this.transform.right; // towards in 2D space is the right of the sprite //} } } /// /// Is the weapon ready to create a new projectile? /// public bool CanAttack { get { return shootCooldown <= 0f; } } }
Questo script ha tre proprietà: il Prefab da utilizzare come sprite da sparare, il tempo minimo da rispettare tra il lancio di un missile ed un altro, e la posizione relativa da dove far partire il missile.
Infine un ultimo passaggio. Modifichiamolo script PlayerScript aggiungendo il seguente codice alla fine del metodo Update.
//5 - Shooting bool shoot = Input.GetButtonDown("Fire1"); shoot |= Input.GetButtonDown("Fire2"); // Careful: For Mac users, ctrl + arrow is a bad idea if (shoot) { WeaponScript weapon = GetComponentAggiungiamo i due script alla nostra astronave e settiamo le proprietà a nostro piacimento. Lanciando il gioco in esecuzione, la nostra astronave sarà ora in grado di lanciare missili a volontà.(); if (weapon != null) { // false because the player is not an enemy weapon.Attack(false); } }
Questo commento è stato eliminato dall'autore.
RispondiElimina