Unity食物忍者

介绍

  • 类似水果忍者

知识点

  •  targetRb.AddTorque扭矩
private Rigidbody targetRb;//用于获取每个物体的刚体组件
targetRb = GetComponent<Rigidbody>();
targetRb.AddTorque(RandomTorque(), RandomTorque(), RandomTorque(), ForceMode.Impulse);//向刚体添加扭矩
 float RandomTorque()
 {
     return Random.Range(-maxTorque, maxTorque);
 }

这段代码看起来像是Unity游戏开发引擎中的C#脚本语句。在Unity中,`Rigidbody`(简称RB)是一个物理组件,用于处理物体的动力学和物理交互。`AddTorque` 是一个Rigidbody的方法,用于给物体施加旋转力矩(torque)。
详细解释如下:
- `targetRb`:这是一个Unity场景中某个物体的Rigidbody组件的引用。`targetRb` 变量名暗示这个Rigidbody是作用在某个特定的目标物体上的。
- `AddTorque`:这是Rigidbody组件的一个方法,用于给物体施加力矩。力矩会使得物体旋转。
- `RandomTorque()`:这是一个假设的方法调用,它没有给出具体实现,但从方法名可以猜测它返回一个随机值,代表力矩的大小。在实际的Unity脚本中,你可能需要自己实现这个方法来生成一个随机的力矩值。
- `ForceMode.Impulse`:这是传递给`AddTorque`方法的`ForceMode`参数,它指定力矩应该如何应用。`ForceMode.Impulse` 表示这个力矩是一次性的,通常用于模拟如碰撞这样的瞬间力。
总结一下,这条语句的作用是给`targetRb`所代表的物体施加一个随机的旋转力矩,这个力矩是一次性的,并且立即应用到物体上。这样的操作可以用来模拟物体在受到冲击或某些外部作用时的旋转效果。

  • 协程
//此方法是正确的
private float spawnRate = 1.0f;//生成目标对象速度
void Start()
{
    StartCoroutine(SpawnTarget());
}
void Update()
{
  //  StartCoroutine(SpawnTarget());
}
IEnumerator SpawnTarget()
{
    while(true)//内部代码完成后才会进行下一次while循环
    {
        yield return new WaitForSeconds(spawnRate);//每暂停1秒后再执行后面代码
        int index=Random.Range(0,targets.Count);
        Instantiate(targets(index));
    }
}
//此方法是错误的
private float spawnRate = 1.0f;//生成目标对象速度
void Start()
{
    //StartCoroutine(SpawnTarget());
}
void Update()
{
    StartCoroutine(SpawnTarget());
}
IEnumerator SpawnTarget()
{
    //while(true)//内部代码完成后才会进行下一次while循环
    //{
        yield return new WaitForSeconds(spawnRate);
        int index=Random.Range(0,targets.Count);
        Instantiate(targets(index));
    //}
}
//Update()一瞬间开启上百个协程,等待1秒后生成大量预制体对象,这是不对的
  • Sensor感应器

用于与物体发生碰撞产生一些事情

  • Mesh Renderer勾选则是渲染出来,不勾选就看不见但还是存在 

  • Wraping:选择Disabled为文本不换行,选择另一个是换行 

  • 添加UI后添加按钮,按钮被点击时触发某个函数

堆(Heap)内存、栈(Stack)内存

  • 基本类型放进栈中,复杂类型放进堆中
  • 例如Person p1=new Person();

new Person();是在堆里开了一个空间存放,而Person p1变量是在栈中,它相当于一个地址(指向堆中地址的指针)

额外

  • 界面中 文件-》生成设置,得到此页面,需要哪个场景往里拖拽哪个场景 

  • GameManager:脚本文件名为此,则游戏的开始 暂停 计分等都在此文件中控制

源码 

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
public class DifficultyButton : MonoBehaviour
{
    private Button button;
    private GameManager gameManager;
    public int difficulty;
    // Start is called before the first frame update
    void Start()
    {
        button = GetComponent<Button>();
        button.onClick.AddListener(SetDifficulty);
        gameManager = GameObject.Find("Game Manager").GetComponent<GameManager>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    void SetDifficulty()
    {
        Debug.Log(gameObject.name + "was clicked");
        gameManager.StartGame(difficulty);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;//场景管理器
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    public List<GameObject> targets;
    //列表,长度不固定,更灵活,查找慢,在堆中开空间以链表的形式存储,可以频繁增删改
    //数组,长度是固定的,遍历时没有数组相比列表是更快的,在栈中(涉及到对象时也会在堆中开空间然后指向)
    //public List targets;这种的不确定列表力放的是哪种类型
    private float spawnRate = 1.0f;//生成目标对象速度
    public TextMeshProUGUI scoreText;
    private int score;
    public TextMeshProUGUI gameOverText;
    public bool isGameActive;//游戏是否结束
    public Button restartButton;
    public GameObject titleScreen;
    //public GameObject gameOverScreen;
    public void StartGame(int difficulty)
    {
        isGameActive = true;
        StartCoroutine(SpawnTarget());//开启协程
        score = 0;
        //scoreText.text = "Score:" + score;
        UpdateScore(0);
        //gameOverText.gameObject.SetActive(true);
        titleScreen.gameObject.SetActive(false);
        spawnRate /= difficulty;
        // restartButton.onClick.AddListener(StartGame);为restartButton按钮绑定事件,当点击此按钮时会调用StartGame函数
        //这防止在场景中拖拽后消失,用此方法不用拖拽
    }
    void Start()
    {
        //InvokeRepeating("SpawnTarget",spawnRate,spawnRate);
    }
    public void GameOver()
    {
        gameOverText.gameObject.SetActive(true);
        isGameActive = false;
        restartButton.gameObject.SetActive(true);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
    /**
     * SpawnTarget()方法的作用就是每隔一秒生成一个随机目标对象
     */
    IEnumerator SpawnTarget()
    {
       // while (true) { }循环非常快,无限循环
        while (isGameActive)//无限循环,这里就是不停的生成目标对象
        {
            //yield在这里相当于暂停的意思
            yield return new WaitForSeconds(spawnRate);//等一秒在执行下方代码
            int index = Random.Range(0, targets.Count);
            Instantiate(targets[index]);
            //UpdateScore(5);
        } 
    }
    public void UpdateScore(int scoreToAdd)
    {
        score += scoreToAdd;
        scoreText.text = "Score:" + score;
    }
    public void RestartGame()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);//获得活动场景名(正在活动运行的场景)
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Target : MonoBehaviour
{
    private Rigidbody targetRb;//用于获取每个物体的刚体组件
    private float minSpeed = 12;
    private float maxSpeed = 16;
    private float maxTorque = 10;
    private float xRange = 4;
    private float ySpawnPos = -6;
    private GameManager gameManager;
    public ParticleSystem explosionParticle;//引入粒子特效
    public int pointValue;
    void Start()
    {
        targetRb = GetComponent<Rigidbody>();
        targetRb.AddForce(RandomForce(), ForceMode.Impulse);
        //targetRb.AddForce(Vector3.up*Random.Range(12,16), ForceMode.Impulse);//给一个向上的力,形式为爆发力
        targetRb.AddTorque(RandomTorque(), RandomTorque(), RandomTorque(), ForceMode.Impulse);//向刚体添加扭矩
        transform.position = RandomSpawnPos();
        gameManager = GameObject.Find("Game Manager").GetComponent<GameManager>();
    }
    Vector3 RandomForce()
    {
        return Vector3.up * Random.Range(minSpeed, maxSpeed);
    }
    float RandomTorque()
    {
        return Random.Range(-maxTorque, maxTorque);
    }
    Vector3 RandomSpawnPos()
    {
        return new Vector3(Random.Range(-xRange, xRange), ySpawnPos);//x轴和y轴,把z轴省略说明z轴是0
    }
    // Update is called once per frame
    void Update()
    {
        
    }
    private void OnMouseDown()//当鼠标点击到与此脚本关联的对象身上时,就触发此函数
    {
        if (gameManager.isGameActive)
        {
            Destroy(gameObject);
            Instantiate(explosionParticle, transform.position, explosionParticle.transform.rotation);
            gameManager.UpdateScore(pointValue);
        }
        

    }
    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);
        if (!gameObject.CompareTag("Bad"))
        {
            gameManager.GameOver();
        }
    }

}

unity打地鼠案例

源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyObjectX : MonoBehaviour
{
    void Start()
    {
        Destroy(gameObject, 2); // destroy particle after 2 seconds
    }


}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DifficultyButtonX : MonoBehaviour
{
    private Button button;
    private GameManagerX gameManagerX;
    public int difficulty;

    // Start is called before the first frame update
    void Start()
    {
        gameManagerX = GameObject.Find("Game Manager").GetComponent<GameManagerX>();
        button = GetComponent<Button>();
        button.onClick.AddListener(SetDifficulty);
    }

    /* When a button is clicked, call the StartGame() method
     * and pass it the difficulty value (1, 2, 3) from the button 
    */
    void SetDifficulty()
    {
        Debug.Log(button.gameObject.name + " was clicked");
        gameManagerX.StartGame(difficulty);
    }



}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameManagerX : MonoBehaviour
{
    public TextMeshProUGUI scoreText;
    public TextMeshProUGUI gameOverText;
    public GameObject titleScreen;
    public Button restartButton;
    public TextMeshProUGUI timerText;

    public List<GameObject> targetPrefabs;

    private int score;
    private float spawnRate = 1.5f;
    public bool isGameActive;

    private float spaceBetweenSquares = 2.5f; 
    private float minValueX = -3.75f; //  x value of the center of the left-most square
    private float minValueY = -3.75f; //  y value of the center of the bottom-most square

    private float timeCount = 60f;
    private float timeLeft;

    private void Start()
    {
        timeLeft = timeCount;
    }
    private void Update()
    {
        timeLeft -= Time.deltaTime;
        if (timeLeft <= 0)
        {
            GameOver();
            
        }
        timerText.text = "Time:" + Mathf.RoundToInt(timeLeft).ToString();
    }

    // Start the game, remove title screen, reset score, and adjust spawnRate based on difficulty button clicked
    public void StartGame(int difficulty)
    {
        spawnRate /= difficulty;
        isGameActive = true;
        StartCoroutine(SpawnTarget());
        score = 0;
        UpdateScore(0);
        titleScreen.SetActive(false);
    }

    // While game is active spawn a random target
    IEnumerator SpawnTarget()
    {
        while (isGameActive)
        {
            yield return new WaitForSeconds(spawnRate);
            int index = Random.Range(0, targetPrefabs.Count);

            if (isGameActive)
            {
                Instantiate(targetPrefabs[index], RandomSpawnPosition(), targetPrefabs[index].transform.rotation);
            }
            
        }
    }

    // Generate a random spawn position based on a random index from 0 to 3
    Vector3 RandomSpawnPosition()
    {
        float spawnPosX = minValueX + (RandomSquareIndex() * spaceBetweenSquares);
        float spawnPosY = minValueY + (RandomSquareIndex() * spaceBetweenSquares);

        Vector3 spawnPosition = new Vector3(spawnPosX, spawnPosY, 0);
        return spawnPosition;

    }

    // Generates random square index from 0 to 3, which determines which square the target will appear in
    int RandomSquareIndex()
    {
        return Random.Range(0, 4);
    }

    // Update score with value from target clicked
    public void UpdateScore(int scoreToAdd)
    {
        score += scoreToAdd;
        scoreText.text = "Score:"+score;
    }

    // Stop game, bring up game over text and restart button
    public void GameOver()
    {
        gameOverText.gameObject.SetActive(true);
        restartButton.gameObject.SetActive(true);
        isGameActive = false;
    }

    // Restart game by reloading the scene
    public void RestartGame()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TargetX : MonoBehaviour
{
    private Rigidbody rb;
    private GameManagerX gameManagerX;
    public int pointValue;
    public GameObject explosionFx;

    public float timeOnScreen = 1.0f;

    private float minValueX = -3.75f; // the x value of the center of the left-most square
    private float minValueY = -3.75f; // the y value of the center of the bottom-most square
    private float spaceBetweenSquares = 2.5f; // the distance between the centers of squares on the game board
    

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        gameManagerX = GameObject.Find("Game Manager").GetComponent<GameManagerX>();

        transform.position = RandomSpawnPosition(); 
        StartCoroutine(RemoveObjectRoutine()); // begin timer before target leaves screen

    }

    // When target is clicked, destroy it, update score, and generate explosion
    private void OnMouseDown()
    {
        if (gameManagerX.isGameActive)
        {
            Destroy(gameObject);
            gameManagerX.UpdateScore(pointValue);
            Explode();
        }
               
    }

    // Generate a random spawn position based on a random index from 0 to 3
    Vector3 RandomSpawnPosition()
    {
        float spawnPosX = minValueX + (RandomSquareIndex() * spaceBetweenSquares);
        float spawnPosY = minValueY + (RandomSquareIndex() * spaceBetweenSquares);

        Vector3 spawnPosition = new Vector3(spawnPosX, spawnPosY, 0);
        return spawnPosition;

    }

    // Generates random square index from 0 to 3, which determines which square the target will appear in
    int RandomSquareIndex ()
    {
        return Random.Range(0, 4);
    }


    // If target that is NOT the bad object collides with sensor, trigger game over
    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);

        if (other.gameObject.CompareTag("Sensor") && !gameObject.CompareTag("Bad"))
        {
            gameManagerX.GameOver();
        } 

    }

    // Display explosion particle at object's position
    void Explode ()
    {
        Instantiate(explosionFx, transform.position, explosionFx.transform.rotation);
    }

    // After a delay, Moves the object behind background so it collides with the Sensor object
    IEnumerator RemoveObjectRoutine ()
    {
        yield return new WaitForSeconds(timeOnScreen);
        if (gameManagerX.isGameActive)
        {
            transform.Translate(Vector3.forward * 5, Space.World);
        }

    }

}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值