الصقيع
الدرس 15 من 18 في دورة لعبة Unity: الدفاع عن الأبراج على Coddy.
برج الصقيع لا يُلحق ضررًا يُذكر، لكن شظاياه تُبطئ العدو لبعض الوقت. الإبطاء حالة تخص عدوًا واحدًا، ولها نهاية: يحتفظ العدو بمعامل الإبطاء والوقت الذي ينتهي عنده، ويحسب سرعته في كل إطار انطلاقًا من سرعة الأصل الخاص به. ما دام Time.time قبل وقت الانتهاء، يُطبَّق المعامل؛ وبعده، يعود العدو إلى سرعته الكاملة من دون الحاجة إلى التراجع عن أي تغيير. سيارة سباق على منصة تعزيز:
public void Boost(float multiplier, float seconds)
{
boost = multiplier;
boostUntil = Time.time + seconds;
}float speed = data.topSpeed;
if (Time.time < boostUntil)
{
speed *= boost;
}يجب ألا يُكتب الإبطاء مطلقًا في الأصل. فالتعبير data.speed *= 0.5f سيُبطئ كل عدو من ذلك النوع، بما في ذلك الأعداء الذين لم يظهروا بعد، ولن يعيد أي شيء السرعة إلى وضعها الأصلي. إذا أصابت شظية ثانية عدوًا مُبطّأً، فإنها تضبط المعامل ووقت الانتهاء من جديد، لذا يستمر الإبطاء ما دام برج الصقيع يواصل إصابة العدو، لكنه لا يزداد قوة.
التحدي
متوسط- في
TowerData، أضف العوامات العامةslowFactor(القيمة الافتراضية 1: بدون إبطاء) وslowDuration(القيمة الافتراضية 0). اضبط FrostData على 0.5 و2. - في
Enemy، أضفpublic void Slow(float factor, float duration)، بحيث يحتفظ بعامل الإبطاء والوقت الذي ينتهي فيه الإبطاء. في كل إطار، تتحرك الشخصية المعادية بسرعة الأصل، مضروبة في العامل طوال مدة الإبطاء. - في
Projectile، بعد إلحاق الضرر، إذا كانت قيمةslowDurationفي البيانات أكبر من 0 وكان الهدف من نوع Enemy، فأبطئه باستخدام عامل البيانات ومدتها.
برج Frost موجود في المتجر، مع الأصل FrostData ومقذوفه FrostShard. اضغط على Play، وضع برج Frost أمام أبراج Arrows، ثم اضغط على Check.
جرّب بنفسك
using System;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour, IDamageable
{
public static readonly List<Enemy> All = new List<Enemy>();
public static event Action<Enemy> ReachedBase;
public static event Action<Enemy> Killed;
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void OnEnable()
{
All.Add(this);
}
void OnDisable()
{
All.Remove(this);
}
void Update()
{
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
if (next == waypoints.Length)
{
ReachedBase?.Invoke(this);
Destroy(gameObject);
}
}
}
public void TakeDamage(int amount)
{
if (health <= 0)
{
return;
}
health -= amount;
if (health <= 0)
{
Killed?.Invoke(this);
Destroy(gameObject);
}
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.