הפכו אותו לשלכם
שיעור 16 מתוך 16 בקורס משחק Unity: שובר לבנים של Coddy.
התכונה האחרונה היא שמירת התוצאה הגבוהה ביותר בין משחקים. PlayerPrefs שומר ערכים קטנים במכשיר של השחקן: PlayerPrefs.GetInt(key, 0) קוראת ערך, עם 0 כשעדיין לא נשמר דבר, ו־PlayerPrefs.SetInt(key, value) שומרת ערך. טען את התוצאה הגבוהה ביותר כשהמשחק מתחיל, ושמור אותה כשהמשחק מסתיים עם תוצאה גבוהה יותר. לחיצה על Play Again טוענת מחדש את הסצנה, ו־GameManager החדש טוען שוב את התוצאה הגבוהה ביותר.
עכשיו המשחק שלך להתאמה אישית. כל מספר שקובע איך הוא מתנהל הוא שדה עם ערך התחלתי בקוד:
Ball:speed(9) ו־minVertical(0.3).Paddle:speed(14),wideFactor(1.6) ו־wideSeconds(8).GameManager:lives(3),dropChance(0.15), והמרווח בין הלבנים.
הפריסות הן רשימת levels של GameManager בחלונית Inspector: ספרה היא לבנה שדורשת מספר פגיעות כזה, נקודה מציינת רווח, ו־/ מתחיל את השורה הבאה, למשל 1.3.1/22222. בפרויקט Unity שלך, שנה את הערכים בחלונית Inspector: ברגע שסקריפט נמצא על אובייקט, חלונית Inspector שומרת עותק משלה, וערך התחלתי חדש בקוד כבר לא מגיע אליו.
אתגר
קשה- ב-
GameManager, הוסףpublic TMP_Text bestText(הסצנה מקשרת ל-BestText) ומשתנהint best. ב-Start(), טען אתbestמתוך PlayerPrefs באמצעות המפתחBestScore, ואתחל ל-0 אם לא נשמר ערך.ShowHud()מציגה גם אתBest: 0ב-bestText, עם התוצאה הטובה ביותר. - כשהמשחק מסתיים עם תוצאה גבוהה יותר מ-
best, שמור אותה ב-best, שמור אותה תחתBestScoreוהצג אותה.
עכשיו הפוך את המשחק לשלך: שנה את המהירויות, את מספר החיים, את הסיכוי להופעת חיזוק ואת עוצמת החיזוקים, ושחק עד שהמשחק מרגיש בדיוק כמו שצריך.
לחץ על Play, קבע תוצאה מיטבית ואז לחץ על Check.
נסו בעצמכם
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Brick brickPrefab;
public Transform wall;
public string[] levels;
public float spacingX = 1.75f;
public float spacingY = 0.75f;
public float topY = 6f;
public Ball ball;
public int lives = 3;
public TMP_Text scoreText;
public TMP_Text livesText;
public GameObject gameOverPanel;
public GameObject[] powerUps;
public float dropChance = 0.15f;
int score;
int level;
int bricksLeft;
List<Ball> balls = new List<Ball>();
void Awake()
{
Instance = this;
}
void Start()
{
balls.Add(ball);
BuildLevel(0);
ShowHud();
}
void BuildLevel(int index)
{
level = index;
string[] rows = levels[index].Split('/');
for (int row = 0; row < rows.Length; row++)
{
string line = rows[row];
float left = -(line.Length - 1) * spacingX / 2f;
for (int col = 0; col < line.Length; col++)
{
char c = line[col];
if (c == '.') continue;
Vector3 pos = new Vector3(left + col * spacingX, topY - row * spacingY, 0f);
Brick brick = Instantiate(brickPrefab, pos, Quaternion.identity, wall);
brick.SetHits(c - '0');
bricksLeft++;
}
}
}
public void BrickBroken(Brick brick)
{
score += brick.points;
bricksLeft--;
ShowHud();
if (Random.value < dropChance)
{
GameObject prefab = powerUps[Random.Range(0, powerUps.Length)];
Instantiate(prefab, brick.transform.position, Quaternion.identity);
}
if (bricksLeft == 0)
{
balls[0].ResetToPaddle();
BuildLevel((level + 1) % levels.Length);
}
}
public void BallLost(Ball lost)
{
if (balls.Count > 1)
{
balls.Remove(lost);
Destroy(lost.gameObject);
return;
}
lives--;
ShowHud();
if (lives == 0)
{
gameOverPanel.SetActive(true);
lost.gameObject.SetActive(false);
}
else lost.ResetToPaddle();
}
public void SplitBall()
{
Ball source = balls[0];
Ball left = Instantiate(source, source.transform.position, Quaternion.identity);
left.Launch(new Vector3(-0.6f, 1f, 0f));
balls.Add(left);
Ball right = Instantiate(source, source.transform.position, Quaternion.identity);
right.Launch(new Vector3(0.6f, 1f, 0f));
balls.Add(right);
}
public void PlayAgain()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
void ShowHud()
{
scoreText.text = "Score: " + score;
livesText.text = "Lives: " + lives;
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.