Unity游戏开发之见缝插针

共 13428字,需浏览 27分钟

 ·

2021-06-02 00:48

作者: 虚拟喵

来源: https://blog.csdn.net/qq_35361471/article/details/79316233

儿童节快乐

成年人也是过了期的小朋友,祝大家节日快乐~~

开发版本:unity 5.3.5f

适合人群:初学Unity者

源文件链接请见文末!

开启学习之旅吧!

场景搭建

创建2D工程StickPin,并创建新场景MainScene,导入素材,完成初始场景搭建

注意工程路径最好不要有中文

在Circle身上挂载脚本RotateSelf.cs,控制圆圈顺时针旋转

public class RotateSelf : MonoBehaviour {
 
    public int speed = 90;
 
    private void Update()
    {
        //方法一:
        transform.Rotate(-Vector3.forward,speed*Time.deltaTime);
        //方法二:
        //transform.Rotate(-new Vector3(0, 0, speed * Time.deltaTime));
        //方法三:
        //transform.Rotate(0, 0, -speed * Time.deltaTime);
    }
}

开发针

制作针,并设为预制体Pin

PinHead设为Pin的子物体,并设置标签PinHead

为针头添加Rigidbody 2D,Circle Collider 2D组件,并设置Gravity Scale为0,勾选Is Trigger

注意,collider需要加上Rigidbody才能完成触发检测

创建两个空对象,StartPoint作为发射针的位置,SpawnPoint作为生成针的位置

在Pin身上挂载脚本Pin.cs

新建方法PinMove

需要注意目标圆的位置targetCirclePos要加一个偏差值,防止针被圆挡住

在Start()方法中完成初始化

 private void Start()
    {
        //GameObject.FindWithTag()需要给对象设置相应标签
        targetTf = GameObject.FindWithTag("StartPoint").transform;
        circle = GameObject.FindWithTag("Circle").transform;
        //偏差值可以根据实际情况调节
        targetCirclePos = circle.position - new Vector3(0, 1.47f, 0);
    }

在Update()方法中调用PinMove()方法

private void Update()
    {
        PinMove();
    }
 
 private void PinMove()
    {
      //isFly判断是否从准备位置StartPoint发射
        if (isFly == false)
        {
            //isReach判断是否从生成位置SpawnPoint移动至发射位置
            if (isReach == false)
            {
                //Vector3.MoveTowards()方法将物体从当前位置直线移动到目标位置
                transform.position = Vector3.MoveTowards(transform.position, targetTf.position, speed * Time.deltaTime);
            }
            //Vector3.Distance()判断两点之间的距离
            //如果针的当前位置距离发射位置小于0.05,则停止运动
            if (Vector3.Distance(transform.position, targetTf.position) < 0.05f)
            {
                transform.position = targetTf.position;
                isReach = true;
            }
        }
        else
        {
            //如果处于发射状态,则针向圆方向移动
            transform.position = Vector3.MoveTowards(transform.position, targetCirclePos, speed * Time.deltaTime);
            if (Vector3.Distance(transform.position, targetCirclePos) < 0.05f)
            {
                //保证针到达圆的目标位置是统一的
                transform.position = targetCirclePos;
                //当前发射针的父对象设置为圆,为了让针跟随圆旋转
                transform.SetParent(circle);
                isFly = false;
            }
        }
    }

新建公共方法StartFly()

//用于外部调用,设置针的发射状态

    public void StartFly()
    {
        isFly = true;
        isReach = true;
    }

在PinHead上挂载脚本PinHead.cs

public class PinHead : MonoBehaviour
{
    //OnTriggerEnter2D在is Trigger勾选下才能起作用,用于2D触发检测
    private void OnTriggerEnter2D(Collider2D collision)
    {
        //如果碰撞物体的tag标签为PinHead,说明碰到其他的针头了
        if (collision.CompareTag("PinHead"))
        {
            // GameObject.Find()根据物体名称,找到GameManager物体
            //GetComponent获取对象身上GameManager组件,调用GameOver方法
            GameObject.Find("GameManager").GetComponent<GameManager>().GameOver();
        }
    }
}

GameManeger游戏管理

新建空对象GameManager,挂载脚本GameManager.cs

创建新方法SpawnPin(),用于生成针,并获得针身上挂载的Pin脚本

 void SpawnPin()
    {
         //GameObject.Instantiate()新生成的对象类型为Object,所以需要强转为GameObject类型
        GameObject pin = GameObject.Instantiate(pinPrefabs, spawnPoint.position, pinPrefabs.transform.rotation) as GameObject;
        //GetComponent用于获取对象的组件,组件名写在<>内
        currentPin = pin.GetComponent<Pin>();
    }

新建一个方法GamOver(),用于结束游戏操作

 public void GameOver()
    {
        //防止两球碰撞,多次调用GameOver方法
        if (isGameOver) return;
        //enabled设为false,则组件失效,圆不能再旋转
        GameObject.FindWithTag("Circle").GetComponent<RotateSelf>().enabled = false;
        isGameOver = true;
    }

在Update()方法类调用SpawnPin方法,鼠标左键点击时,发射当前针,并生成新的针

 private void Update()
    {
        //isGameOVer为false,则游戏结束,直接返回,不再执行下面命令
        if (isGameOver) return;
        //Input.GetMouseButtonDown(0)监听鼠标左键点击事件
        if (Input.GetMouseButtonDown(0))
        {
            //调用针的StartFly方法,设置针发射
            currentPin.StartFly();
            //当前针发射后,再生成针,完成连续发射功能
            SpawnPin();
        }
    }

控制分数显示,设置两个全局变量,注意需要引入命名空间

using UnityEngine.UI;

public Text scoreText;

public int score;

可以在Inspector面板完成赋值

在Update方法内添加,如下加粗语句,完成分数的增加和显示。微信搜索公众号 [爱上游戏开发],回复 “资料”,免费领取 200G 学习资料

        if (Input.GetMouseButtonDown(0))
        {
           //score自增1
            score++;
            //ToString()将数值score转为字符串
            scoreText.text = score.ToString();
            //调用针的StartFly方法,设置针发射
            currentPin.StartFly();
            //当前针发射后,再生成针,完成连续发射功能
            SpawnPin();
        }

使用协程实现场景结束效果

  //IEnumerator(迭代器)
    IEnumerator GameOverAnimation()
    {
        while (true)
        {
            //Lerp线性插值运算,以此实现渐变效果
            mainCamera.backgroundColor = Color.Lerp(mainCamera.backgroundColor, Color.red, speed * Time.deltaTime);
            mainCamera.orthographicSize = Mathf.Lerp(mainCamera.orthographicSize, 4, speed * Time.deltaTime);
            //当到达目标值,则跳出循环
            if (Mathf.Abs(mainCamera.orthographicSize - 4) < 0.01f)
            {
                break;
            }
            //可理解为每循环一次暂停一帧,下一帧继续,如果不加这句,渐变效果会瞬间完成 
            yield return 0;
        }
        //完成循环后,等待0.2秒
        yield return new WaitForSeconds(0.2f);
        //重新加载当前场景
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

需要在GameOver()方法内开启协程


 public void GameOver()
    {
        if (isGameOver) return;
        GameObject.FindWithTag("Circle").GetComponent<RotateSelf>().enabled = false;
        //开启协程
        StartCoroutine(GameOverAnimation());
        isGameOver = true;
    }

添加音乐音效

在MainCamera上添加组件AudioSource,audioclip设置背景音乐,勾选play on awake,loop选项

Volume控制音量,适量调节

在GameManager.cs中

添加public AudioClip clip,inspector面板中赋值

Update()方法中添加AudioSource.PlayClipAtPoint

if (Input.GetMouseButtonDown(0))
        {
            score++;
            scoreText.text = score.ToString();
            currentPin.StartFly();
            AudioSource.PlayClipAtPoint(clip,Camera.main.transform.position);
            SpawnPin();
        }

发布PC端

File-BuildSettings 点击Build完成打包,注意打包出的文件要放在同一个文件夹内

至此,见缝插针基础案例开发完成,为了督促自己学习,以后会陆续写一些博客,帮助更多和我一样喜欢游戏开发的同学!

素材及工程文件百度云链接:链接:https://pan.baidu.com/s/1qZqBdYO 密码:3u1t


-- END --


公众号后台回复「资料」获取超多学习福利

>>> 点击进入技术讨论群 <<<
▽想深入了解么?

长按/扫码关注我吧↑↑↑


觉得不错就点个在看

浏览 58
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报