Unity官方教程 - 示例代码

Roll A Ball
  • PlayerController.cs

/*
* PlayerController.cs
*/

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour
{
    public float speed;
    public Text grade;
    public Text win;
    public Button restartBtn;

    float h;
    float v;
    int count;

    Rigidbody rb;

    // Use this for initialization
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");
        Vector3 force = new Vector3(h, 0f, v);
        rb.AddForce(force * speed * Time.deltaTime);
    }

    // Update is called once per frame
    void Update()
    {
        grade.text = "Grade : " + count;
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Collection")
        {
            Destroy(other.gameObject);

            count += 1;

            if (count == 10)
            {
                win.gameObject.SetActive(true);
                restartBtn.gameObject.SetActive(true);
            }
        }
    }

    public void restartGame()
    {
        SceneManager.LoadScene("Main", LoadSceneMode.Single);
    }
}


  • CameraController.cs

/*
* CameraController.cs
*/

using UnityEngine;

public class CameraController : MonoBehaviour
{

    public Transform player;
    Vector3 offset;

    // Use this for initialization
    void Start()
    {
        offset = player.position - transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = player.position - offset;
    }
}


  • CollectionsController.cs

/*
* CollectionsController.cs
*/

using UnityEngine;

public class CollectionController : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        Vector3 rotation = new Vector3(1, 1, 1);
        transform.Rotate(rotation);
    }
}

Space Shooter
  • PlayerController.cs
using UnityEngine;


// 定义飞行边界
[System.Serializable]
public class Boundary
{
    public float xMin, xMax, zMin, zMax;
}

public class PlayerController : MonoBehaviour
{
    public Boundary boundary;
    public float speed;
    public float tilt;

    public GameObject shot;
    public Transform shotSpawn;
    public float fireRate;
    private float nextFire;

    Rigidbody rb;


    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;

            Instantiate(shot, shotSpawn.position, shotSpawn.rotation);

            GetComponent<AudioSource>().Play();
        }
    }

    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        rb = GetComponent<Rigidbody>();

        Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);
        movement *= speed;

        rb.velocity = movement;

        // 限制飞行边界
        rb.position = new Vector3(
            Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
            0f,
            Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax)
            );

        // 添加运动倾斜
        rb.rotation = Quaternion.Euler(0f, 0f, rb.velocity.x * -tilt);
    }
}

  • GameController.cs
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// System.Collections
/// 协程需使用该命名空间
/// </summary>

public class GameController : MonoBehaviour
{
    public GameObject[] hazards;
    public Vector3 spawnValues;
    public int hazardCount;
    public float startWait;
    public float spawnWait;
    public float waveWait;

    public Text scoreText;
    public Text restartText;
    public Text gameoverText;

    private int score;
    private bool bGameOver;
    private bool bRestart;


    // Use this for initialization
    void Start()
    {
        bGameOver = false;
        bRestart = false;
        restartText.text = "";
        gameoverText.text = "";

        score = 0;
        UpdateScore();

        // 延时函数
        //InvokeRepeating("GenerateHazards", 2f, 2f);
        // 使用协程实现一波又一波的行星生成
        StartCoroutine(SpawnWaves());
    }

    IEnumerator SpawnWaves()
    {
        while (true)
        {
            yield return new WaitForSeconds(startWait);

            for (int i = 0; i < hazardCount; i++)
            {
                Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
                Quaternion spawnRotation = Quaternion.identity;
                Instantiate(hazards[Random.Range(0, hazards.Length)], spawnPosition, spawnRotation);

                yield return new WaitForSeconds(spawnWait);
            }

            // 稍作停顿 开始下一波灾难
            yield return new WaitForSeconds(waveWait);

            if (bGameOver)
            {
                restartText.text = "Please press 'R' for restart";
                bRestart = true;
                break;
            }
        }
    }

    void GenerateHazards()
    {
        Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
        Quaternion spawnRotation = Quaternion.identity;
        Instantiate(hazards[Random.Range(0, hazards.Length)], spawnPosition, spawnRotation);
    }

    void UpdateScore()
    {
        scoreText.text = "Score : " + score;
    }
	
    // Update is called once per frame
    void Update()
    {
        // 仅检测有无重新开始游戏的请求
        if (bRestart)
        {
            if (Input.GetKeyDown(KeyCode.R))
            {
                // 重新加载场景
                SceneManager.LoadScene("Main", LoadSceneMode.Single);
            }
        }
    }

    // interface
    // 计算分数
    public void AddScore(int newScoreVal)
    {
        score += newScoreVal;
        UpdateScore();
    }

    // 游戏结束
    public void GameOver()
    {
        gameoverText.text = "Game Over ! ";
        bGameOver = true;
    }
}

  • DestroyByContact.cs
using UnityEngine;

public class DestroyByContact : MonoBehaviour
{
    public GameObject asteroidExplosion;
    public GameObject playerExplosion;

    public int scoreVal;
    
	// 引用外部类
    private GameController gameController;


    // Use this for initialization
    void Start()
    {
        // FindWithTag找到GameObject实例
        GameObject gameControllerObject = GameObject.FindWithTag("GameController");

        if (gameControllerObject != null)
        {
            // GameObject中有多个组件,GetComponent找到其脚本组件
            gameController = gameControllerObject.GetComponent<GameController>();
        }
        else
        {
            Debug.Log("Can not find 'GameController' script");
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Boundary")
        {
            return;
        }

        if (other.tag == "Player")
        {
            // 实例化玩家爆炸预制体
            Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
            gameController.GameOver();

        }
        else
        {
            // 行星自身爆炸预制体
            Instantiate(asteroidExplosion, transform.position, transform.rotation);
        }
        Destroy(other.gameObject);
        Destroy(gameObject); // 销毁自身

        gameController.AddScore(scoreVal);

        // 爆炸预制体还未销毁,因其无法触及销毁边界,故添加定时销毁
        // 定时销毁脚本挂载在爆炸预制体自身

    }

}

  • Mover.cs
using UnityEngine;

public class Mover : MonoBehaviour
{

    public float speed;
    Rigidbody rb;
	
    // Use this for initialization
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.velocity = transform.forward * speed;
    }

}

  • RandomRotator.cs
using UnityEngine;

public class RandomRotator : MonoBehaviour
{

    // 陨石随机旋转
    public float tumble;
    Rigidbody rb;

    // Use this for initialization
    void Start()
    {
        rb = GetComponent<Rigidbody>();

        // 添加旋转角速度 insideUnitSphere:返回半径为1球体内的一个随机点
        rb.angularVelocity = Random.insideUnitSphere * tumble;
    }

}

  • DestroyByBoundary.cs
using UnityEngine;

public class DestroyByBoundary : MonoBehaviour
{

    void OnTriggerExit(Collider other)
    {
        Destroy(other.gameObject);
    }

}

  • DestroyByTime.cs
using UnityEngine;
using System.Collections;

public class DestroyByTime : MonoBehaviour
{

    public float lifetime;

    // Use this for initialization
    void Start()
    {
        Destroy(gameObject, lifetime);
    }

}

Survival Shooter

该项目脚本较多,首先来剖析player相关脚本
在这里插入图片描述

  • PlayerHealth.cs
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

/*
 * PlayerHealth
 * 玩家生命管理 受到伤害处理
*/

public class PlayerHealth : MonoBehaviour
{

    public int startingHealth = 100;
    public int currentHealth;

    public AudioClip deathClip;

    Animator anim;
    AudioSource playerAudio;
    PlayerMovement playerMovement;
    PlayerShooting playerShooting;
    bool isDead;
    bool damaged;

    // 添加UI相关控件
    public Slider healthSlider;
    public Image damageImage;
    public Color flashColor = new Color(1f, 0f, 0f, 0.1f); // 闪动接近透明的红色

    public float flashSpeed = 5f;

    void Awake()
    {
        anim = GetComponent<Animator>();
        playerAudio = GetComponent<AudioSource>();
        playerMovement = GetComponent<PlayerMovement>();
        playerShooting = GetComponentInChildren<PlayerShooting>();
        currentHealth = startingHealth;
    }

    void Update()
    {
        if (damaged)
        {
            damageImage.color = flashColor;

            // 闪动一下 则还原白色纯透明
            //damageImage.color = Color.Lerp(damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }
        else
        {
            damageImage.color = Color.Lerp(damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }

        damaged = false;
    }

    // interface
    // Enemy Attack 调用
    public void TakeDamage(int amount)
    {
        damaged = true;

        currentHealth -= amount;

        healthSlider.value = currentHealth;

        playerAudio.Play();

        if (currentHealth <= 0 && !isDead)
        {
            Death();
        }
    }

    void Death()
    {
        isDead = true;

        playerShooting.DisableEffects();

        anim.SetTrigger("Die");

        playerAudio.clip = deathClip;
        playerAudio.Play();

        playerMovement.enabled = false;
        playerShooting.enabled = false;
    }

    // Player Death Animation Event 调用
    public void RestartLevel()
    {
        /*
         * 重新加载场景后光照可能变暗
         * 因为选择的光照是realtime实时光照
         * 编辑器在当前场景时候,光照是已经渲染好的
         * 重新加载的时候光照没有进行渲染
         * 需要预烘焙,以便保存光照贴图信息
         * windows -> lighting 取消勾选Auto 再点击旁边的Build 
         */
        //SceneManager.LoadScene("Main", LoadSceneMode.Single); // 重新加载场景
        //SceneManager.LoadScene("Main", LoadSceneMode.Additive); // 在现有场景基础上继续游戏
        SceneManager.LoadScene("Main"); // Mode可省

    }

}
  • PlayerMovement.cs
using UnityEngine;

/*
 * Survival Shooter
 * PlayerMovement
 */

public class PlayerMovement : MonoBehaviour
{

    public float speed = 6f;

    Animator anim;
    Rigidbody playerRigidbody;

    Vector3 movement;

    int floorMask; // 方便定义射线仅与地板相交
    float camRayLength = 100f; // 射线长度

    // 初始化一些引用
    void Awake()
    {
        floorMask = LayerMask.GetMask("Floor");
        anim = GetComponent<Animator>();
        playerRigidbody = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        // GetAxisRaw 直接返回-1 1 在FPS游戏中可实现立即转向
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        Move(h, v);
        Turning();
        Animating(h, v);
    }

    void Move(float h, float v)
    {
        // Gravity On
        movement.Set(h, 0f, v);
        movement = movement.normalized * speed * Time.deltaTime;

        playerRigidbody.MovePosition(transform.position + movement);

        // Gravity Off
        //movement.Set(h, 0f, v);
        //movement = movement.normalized * speed * Time.deltaTime;
        //playerRigidbody.velocity = movement;
    }

    // 玩家转向朝向射线与地板的相交点
    void Turning()
    {
        Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit floorHit;

        // 确保射线只能与地面相交
        if (Physics.Raycast(camRay, out floorHit, camRayLength, floorMask))
        {
            Vector3 playerToMouse = floorHit.point - transform.position;
            playerToMouse.y = 0f;
            // 构建旋转四元数
            //Quaternion playerRotation = Quaternion.identity;
            Quaternion playerRotation = Quaternion.LookRotation(playerToMouse);
            playerRigidbody.MoveRotation(playerRotation);
        }
    }

    void Animating(float h, float v)
    {
        bool walking = h != 0f || v != 0f;
        anim.SetBool("IsWalking", walking);
    }
}

  • PlayerShooting.cs
using UnityEngine;

/*PlayerShooting
 * 挂载在Player -> GunBarrelEnd
 * 并设置Environment Layer Shootable
 * Enemy Shootable
 * Light 开火高亮
 * Line Render 绘制激光线
*/

public class PlayerShooting : MonoBehaviour
{
    public int damagePerShot = 20;
    public float timeBetweenBullets = 0.15f;
    public float range = 100f; // 激光射线最长距离

    float timer;
    Ray shootRay;
    RaycastHit shootHit;
    int shootableMask;

    ParticleSystem gunParticles;
    Light gunLight;
    LineRenderer gunLine;
    AudioSource gunAudio;

    float effectDisplayTime = 0.2f;


    void Awake()
    {
        shootableMask = LayerMask.GetMask("Shootable");
        gunParticles = GetComponent<ParticleSystem>();
        gunLine = GetComponent<LineRenderer>();
        gunAudio = GetComponent<AudioSource>();
        gunLight = GetComponent<Light>();
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;

        if (Input.GetButton("Fire1") && timer >= timeBetweenBullets && Time.timeScale != 0)
        {
            Shoot();
        }

        if (timer >= timeBetweenBullets * effectDisplayTime)
        {
            DisableEffects();
        }

    }

    void Shoot()
    {
        timer = 0f;

        gunAudio.Play();
        gunLine.enabled = true;
        gunLight.enabled = true;
        gunParticles.Stop();
        gunParticles.Play();

        gunLine.SetPosition(0, transform.position);

        shootRay.origin = transform.position;
        shootRay.direction = transform.forward;

        // 与shootable物体相交测试
        if (Physics.Raycast(shootRay, out shootHit, range, shootableMask))
        {
            // 绘制激光线
            gunLine.SetPosition(1, shootHit.point);

            // 击中的胶囊体碰撞器所属的对象(GameObject)得到其EnemyHealth
            EnemyHealth enemyHealth = shootHit.collider.GetComponent<EnemyHealth>();
            if (enemyHealth != null)
            {
                enemyHealth.TakeDamage(damagePerShot, shootHit.point);
            }
        }
        else
        {
            gunLine.SetPosition(1, shootRay.origin + shootRay.direction * range);
        }
    }

    public void DisableEffects()
    {
        gunLine.enabled = false;
        gunLight.enabled = false;
    }
}

再来剖析Enemy相关脚本
在这里插入图片描述

  • EnemyAttack.cs
using UnityEngine;

/*
 * EnemyAttack
 * 
*/

public class EnemyAttack : MonoBehaviour
{

    public float timeBetweenAttacks = 0.5f;
    public int attackDamage = 10;

    Animator anim;
    GameObject player;
    PlayerHealth playerHealth;
    EnemyHealth enemyHealth;

    bool playerInRange;
    float timer;

    void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        playerHealth = player.GetComponent<PlayerHealth>();
        enemyHealth = GetComponent<EnemyHealth>();
        anim = GetComponent<Animator>();
    }

    // Sphere Collider
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject == player) // if (other.tag == "player")
        {
            playerInRange = true;
        }
    }

    void OnTriggerExit(Collider other)
    {
        if (other.gameObject == player)
        {
            playerInRange = false;
        }
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;

        if (timer >= timeBetweenAttacks && playerInRange && enemyHealth.currentHealth > 0)
        {
            Attack();
            timer = 0f;
        }

        if (playerHealth.currentHealth <= 0)
        {
            anim.SetTrigger("PlayerDead"); // Enemy切换到Idle状态
        }
    }

    void Attack()
    {
        if (playerHealth.currentHealth > 0)
        {
            playerHealth.TakeDamage(attackDamage);
        }
    }

}

  • EnemyHealth.cs
using UnityEngine;


/*
 * EnemyHealth
 * 敌人生命管理 受到伤害相关
 */

public class EnemyHealth : MonoBehaviour
{
    public int startingHealth = 100;
    public int currentHealth;

    // Dead后会下沉消失
    public float sinkSpeed = 2.5f;
    public int scoreValue = 10;
    public AudioClip deathClip;

    Animator anim;
    AudioSource enemyAudio;
    ParticleSystem hitParticles;
    CapsuleCollider capsuleCollider;
    bool isDead;
    bool isSinking;


    void Awake()
    {
        anim = GetComponent<Animator>();
        enemyAudio = GetComponent<AudioSource>();
        hitParticles = GetComponentInChildren<ParticleSystem>();
        capsuleCollider = GetComponent<CapsuleCollider>();

        currentHealth = startingHealth;
    }

    // Update is called once per frame
    void Update()
    {
        if (isSinking)
        {
            transform.Translate(-Vector3.up * sinkSpeed * Time.deltaTime);
        }
    }

    // interface

    // 受到攻击
    public void TakeDamage(int amount, Vector3 hitPoint)
    {
        if (isDead)
            return;

        enemyAudio.Play();

        currentHealth -= amount;

        // 粒子特效
        hitParticles.transform.position = hitPoint;
        hitParticles.Play();

        if (currentHealth <= 0)
        {
            Death();
        }
    }

    //  Enemy Death Animation Event 调用
    // 死亡后下沉
    public void StartSinking()
    {
        GetComponent<NavMeshAgent>().enabled = false;
        GetComponent<Rigidbody>().isKinematic = true; // 运动不受物理力影响
        isSinking = true;
        ScoreManager.score += scoreValue;
        Destroy(gameObject, 2f);
    }

    void Death()
    {
        isDead = true;

        capsuleCollider.isTrigger = true;

        anim.SetTrigger("Dead");

        // 更换其声音片段为死亡音效
        enemyAudio.clip = deathClip;
        enemyAudio.Play();
    }
}

  • EnemyMovement.cs
using UnityEngine;

/*
 * EnemyMovement
 * Nav Mesh Agent 组件
*/

public class EnemyMovement : MonoBehaviour
{

    Transform player;
    EnemyHealth enemyHealth;
    NavMeshAgent nav;

    void Awake()
    {
        // InvokeRepeating 自动重复生成敌人,故使用FindGameObjectWithTag查找玩家
        player = GameObject.FindGameObjectWithTag("Player").transform;
        enemyHealth = GetComponent<EnemyHealth>();

        // 得到导航网格
        nav = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
        if (enemyHealth.currentHealth > 0)
        {
            nav.SetDestination(player.position);
        }
    }
}

接着继续剖析Managers相关
在这里插入图片描述

  • EnemyManager.cs
using UnityEngine;


/*
 * EnemyManager
 * Windows -> Aavigation 预烘焙导航网格
 * Nav Mesh Agent 添加AI导航组件
 * Animator Override Controller 可以重载不同敌人的动画动作
 * 将该脚本在EnemyManager下重复挂载多次便于升车多类对象,enemy设置不同的数值
*/

public class EnemyManager : MonoBehaviour
{
    public GameObject enemy;
    public float spawnTime = 3f;
    public Transform[] spawnPoints; // 在编辑器中设置生成点

    // Use this for initialization
    void Start()
    {
        // 调用重复延时函数
        InvokeRepeating("Spawn", spawnTime, spawnTime);
        // Invoke("Spawn", spawnTime);
    }

    void Spawn()
    {
        // 暂时先在原点生成
        //Vector3 spawnPos = Vector3.zero;
        //Quaternion spawnRotation = Quaternion.identity;
        //Instantiate(enemy, spawnPos, spawnRotation);

        int spawnPointIndex = Random.Range(0, spawnPoints.Length);
        Instantiate(enemy, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
    }

}

  • GameOverManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;


/*
 * GameOverManager
 * 该脚本挂载在Canvas(画布),即最顶层UI上
*/

public class GameOverManager : MonoBehaviour
{

    public PlayerHealth playerHealth;
    public float restartDelay = 5f; // 在5s后重新开始游戏

    Animator anim; // 将UI图形渐变制作成AC动画 (淡入淡出相关) Windows -> Animation
    float restartTimer;


    void Awake()
    {
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (playerHealth.currentHealth <= 0)
        {
            anim.SetTrigger("GameOver");

            restartTimer += Time.deltaTime;

            if (restartTimer > restartDelay)
            {
                // 重新开始游戏,加载场景
                // 需要去掉PlayerHealth RestartLeve1的调用(delete Animation Event)
                SceneManager.LoadScene("Main");
            }
        }
    }

    // PlayerHealth.cs 相关相同功能代码
    // Player Death Animation Event 调用
    //public void RestartLevel()
    //{
    //    /*
    //     * 重新加载场景后光照可能变暗
    //     * 因为选择的光照是realtime实时光照
    //     * 编辑器在当前场景时候,光照是已经渲染好的
    //     * 重新加载的时候光照没有进行渲染
    //     * 需要预烘焙,以便保存光照贴图信息
    //     * windows -> lighting 取消勾选Auto 再点击旁边的Build 
    //     */
    //    //SceneManager.LoadScene("Main", LoadSceneMode.Single); // 重新加载场景
    //    //SceneManager.LoadScene("Main", LoadSceneMode.Additive); // 在现有场景基础上继续游戏
    //    SceneManager.LoadScene("Main"); // Mode可省
    //}
}

  • ScoreManager.cs
using UnityEngine;
using UnityEngine.UI;

/*
 * ScoreManager
 * 该脚本挂载在UI控件ScoreText上
*/

public class ScoreManager : MonoBehaviour
{
    /*外部可通过该类直接访问该变量,无需实例化,在EnemyHealth脚本 Enemy Death中进行分数累加
     * ScoreManager.score += scoreValue;
     */
    public static int score;

    Text text;

    void Awake()
    {
        text = GetComponent<Text>();
        score = 0;
    }

    // Update is called once per frame
    void Update()
    {
        text.text = "Score: " + score;
    }
}

最后剖析Camera跟随脚本
在这里插入图片描述

  • CameraFollow.cs
using UnityEngine;
using System.Collections;

/*
 * CameraFollow
*/

public class CameraFollow : MonoBehaviour
{

    public Transform target;
    public float smoothing = 5f; // 平滑插值 防止摄像机移动中抖动

    Vector3 offset;

    // Use this for initialization
    void Start()
    {
        offset = target.position - transform.position;
    }

    void FixedUpdate()
    {
        // default 0.02s
        // transform.position = target.position - offset;
        Vector3 targetCameraPos = target.position - offset;
        // 平滑插值
        transform.position = Vector3.Lerp(transform.position, targetCameraPos, smoothing * Time.deltaTime); // 0.1 平滑系数
    }
}

UFO Game
  • PlayerController.cs
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour
{

    public float speed;
    private Rigidbody2D rb2d;

    public Text countText;
    public Text winText;
    public Text restartText;
    int count;

    bool bRestart;

    // Use this for initialization
    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
        winText.text = "";
    }

    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector2 movement = new Vector2(moveHorizontal, moveVertical);
        rb2d.AddForce(movement * speed * Time.deltaTime);
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        //if (other.tag == "PickUp")
        //{
        //    other.gameObject.SetActive(false);
        //    count += 1;
        //    SetCountText();
        //}


        if (other.gameObject.CompareTag("PickUp"))
        {
            other.gameObject.SetActive(false);
            //Destroy(other.gameObject);

            count = count + 1;

            SetCountText();
        }
    }

    void SetCountText()
    {
        countText.text = "Grade: " + count.ToString();

        if (count >= 12)
        {
            // winText.gameObject.SetActive(true); // 可在编辑器中将text直接置空
            winText.text = "You Win!";

            // 重新开始游戏按键提示
            restartText.text = "Please press 'R' for restart";
            bRestart = true;
        }
    }

    void Update()
    {
        if (bRestart)
        {
            if (Input.GetKeyDown(KeyCode.R))
            {
                // 重新加载游戏场景
                SceneManager.LoadScene("Main");
            }
        }
    }


}

  • Rotator.cs
using UnityEngine;

public class Rotator : MonoBehaviour
{
    void Update()
    {
        // transform.Rotate(0, 0, 1); // 2D绕Z轴旋转即可
        transform.Rotate(new Vector3(0, 0, 45) * Time.deltaTime);
    }
}

  • CameraFollow.cs
using UnityEngine;
using System.Collections;

public class CameraFollow : MonoBehaviour
{

    public GameObject player;

    private Vector3 offset;

    // Use this for initialization
    void Start()
    {
        offset = player.transform.position - transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = player.transform.position - offset;
    }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值