Menu
CoddyTech

רעידות מצלמה

חלק מהיחידה פיזיקה ומשחקיות במסלול ה-Unity של Coddy. שיעור 50 מתוך 71.

טלטול הוא רצף קצר של היסטים אקראיים: במשך כמה עשיריות השנייה המצלמה נמצאת בנקודה אקראית בקרבת מיקום המנוחה שלה, נקודה חדשה בכל פריים, ואז היא חוזרת למקומה. קורוטינה מתאימה לכך, כי היא פועלת לאורך כמה פריימים ומסתיימת מעצמה. המצלמה הזאת רועדת כשסלע נוחת (סקריפט אחר קורא ל־BoulderLanded(); הקובץ מתחיל ב־using System.Collections; עבור IEnumerator):

public float strength = 0.2f;
public float duration = 0.4f;
Vector3 rest;

void Start()
{
    rest = transform.localPosition;
}

public void BoulderLanded()
{
    StartCoroutine(Shake());
}

IEnumerator Shake()
{
    float elapsed = 0f;
    while (elapsed < duration)
    {
        transform.localPosition = rest + Random.insideUnitSphere * strength;
        elapsed += Time.deltaTime;
        yield return null;
    }
    transform.localPosition = rest;
}

Random.insideUnitSphere * strength הוא היסט אקראי באורך של עד strength בכל כיוון, ו־yield return null בוחר היסט חדש בפריים הבא. הוספת Time.deltaTime בכל איטרציה סופרת שניות בפועל, כך שהטלטול נמשך duration בכל קצב פריימים. השורה האחרונה מחזירה את המצלמה למקומה; בלעדיה, המצלמה נשארת במקום שאליו הביא אותה ההיסט האחרון.

בכל פריים Unity מריצה כל Update(), ואז את הקורוטינות שממתינות ל־yield return null, ואז כל LateUpdate(). לכן מצלמת מעקב שמגדירה את המיקום שלה ב־LateUpdate() דורסת את כל מה שהטלטול עשה. טלטול של localPosition מונע זאת כשהמצלמה היא צאצא של אובייקט ריק שאחראי למעקב: ההורה נע, והמצלמה רועדת סביב מיקומה ביחס אליו.

challenge icon

אתגר

בינוני

נערו את המצלמה הבאה בלחיצה על מקש הרווח.

  1. הוסיפו שדה Vector3 shake;, ובתוך LateUpdate() הגדירו transform.position = player.position + offset + shake;.
  2. בתוך Shake(), כל עוד elapsed < duration: shake = Random.insideUnitSphere * strength;, הוסיפו את Time.deltaTime ל־elapsed, ואז yield return null;.
  3. אחרי הלולאה, הגדירו shake = Vector3.zero;.

לחצו על "שחק", רוצו ולחצו על מקש הרווח: התצוגה תרעד תוך כדי מעקב אחריכם. לאחר מכן לחצו על "בדיקה".

נסו בעצמכם

using System.Collections;
using UnityEngine;

public class ShakeFollow : MonoBehaviour
{
    public Transform player;
    public Vector3 offset = new Vector3(0, 4, -8);
    public float strength = 0.3f;
    public float duration = 0.4f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Shake());
        }
    }

    void LateUpdate()
    {
        transform.position = player.position + offset;
    }

    IEnumerator Shake()
    {
        // הרעד את המצלמה למשך duration שניות, במרחק של עד strength ממיקום המעקב שלה.
        yield return null;
    }
}

כל השיעורים ביחידה פיזיקה ומשחקיות

תרגלו בעצמכם: Unity אונליין