我是靠谱客的博主 感性大叔,最近开发中收集的这篇文章主要介绍Unity 电路解密小游戏实现思路实现效果功能需求实现思路实现过程总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实现效果

效果展示视频
项目Github
在这里插入图片描述

功能需求

点击电线组件可以旋转,连接电池首尾游戏结束(该Demo还要连通特殊组件),连通后线路会亮起来(该Demo只要和正极相连的线路就会亮,Demo的亮是图片颜色变化和Unity光照,这里就写图片的颜色变化,思路是差不多的)。不需要记录正确路线的所有电线组件的正确方向,将电路组件做成prefab后,可以由策划自由放置,判断是否连接正确由组件之间的自行判断。

实现思路

为每个电线组件添加接口Trigger,点击组件后组件进行旋转,将接口触发到的线路引用添加进来,将离开的线路引用删除,然后发送事件,重置所有让电池开始从正极的电线开始递归调用显示。

实现过程

创建电线组件

创建一个空物体命名为Line_A并添加Tag为Line,在其下创建俩个空物体,一个命名为Images用来存放图片,一个命名为CheckPoints用来存放检测点并为其子物体添加Tag为CheckPoint。
在这里插入图片描述
给Line_添加BoxCollider2D,调整好大小覆盖整个线路,这个Collider是用来检测鼠标的点击旋转的。再给Points下的物体添加BoxCollider2D,并勾选is Trigger,再添加RigidBody2D,并设计BodyType为Kinematic,这个是用来判断线路之间的连接情况的。

在这里插入图片描述
给Line_A添加Line.cs脚本,并把图片拖拽上去

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering.Universal;

public class Line : MonoBehaviour
{
    public bool isPower;//用来判断该线路组件是否处于通电状态
    public List<GameObject> nextLines = new List<GameObject>();//连接线路的引用
    public SpriteRenderer spriteRenderer;//图片

    public void Rotate()
    {
        this.transform.Rotate(0, 0, -90);
    }
    public void AddNextLine(GameObject line)
    {
        nextLines.Add(line);
    }
    public void DeleteNextLine(GameObject line)
    {
        nextLines.Remove(line);
    }

    /// <summary>
    /// 通电递归
    /// </summary>
    public void Power()
    {
        Debug.Log(this.transform.name + "通电了");
        isPower = true;
        // 通电效果
        SetLuminance(true);
        //给连接的线路通电
        foreach (GameObject nextLine in nextLines)
        {
            var line = nextLine.GetComponent<Line>();
            if (!line.isPower)
            {
                line.Power();
            }
        }
    }

    /// <summary>
    /// 重置状态
    /// </summary>
    public void ResetStatic()
    {
        isPower = false;
        SetLuminance(false);
    }
    /// <summary>
    /// 通电后颜色变化
    /// </summary>
    /// <param name="p">true变红/false变会原来的颜色</param>
    public void SetLuminance(bool p)
    {
        if (p)
        {
            spriteRenderer.color = new Color32(240, 124, 130, 255);
        }
        else
        {
            spriteRenderer.color = new Color(1f, 1f, 1f, 1f);
        }

    }
}

给CheckPoint添加CheckPoint.cs,并拖拽父对象的引用

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

public class CheckPoint : MonoBehaviour
{
    public Line line;
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("连接到线路");
            line.AddNextLine(other.transform.parent.parent.gameObject);
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("断开线路");
          line.DeleteNextLine(other.transform.parent.parent.gameObject);
        }
    }
}

同理,我们可以再设计更多线路预制体
在这里插入图片描述
在这里插入图片描述

创建电池组件

同理电线的制作
在这里插入图片描述
为Battery添加Battery.cs

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

public class Battery : MonoBehaviour
{
    public GameObject outLine;//正极连接的线
    public GameObject inLine;//负极连接的线

    /// <summary>
    /// 开始通电
    /// </summary>
    public void StartPower()
    {
        if (outLine != null)
        {
            //Debug.Log("电池开始通电");
            outLine.GetComponent<Line>().Power();
        }
    }
}

把Points下的对象的CheckPoint.cs换成InPole.cs和OutPole.cs

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

/// <summary>
/// 负极
/// </summary>
public class InPole : MonoBehaviour
{
    public Battery battery;
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("连接到线路");
            battery.inLine = other.transform.parent.parent.gameObject;
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("断开线路");
            battery.inLine = null;
        }
    }
}

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

/// <summary>
/// 正极
/// </summary>
public class OutPole : MonoBehaviour
{
    public Battery battery;
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("连接到线路");
            battery.outLine = other.transform.parent.parent.gameObject;
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("CheckPoint"))
        {
            //Debug.Log("断开线路");
            battery.outLine = null;
        }
    }
}

鼠标点击管理类

在场景中创建空物体命名为Cursor Manager,添加CursorManager.cs单例类,鼠标点击后检测周围的碰撞体,如果Tag是Line,则调用它的旋转方法,
然后发送让关卡管理类指挥通电。

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

/// <summary>
/// 管理鼠标点击
/// </summary>
public class CursorManager : Singleton<CursorManager>
{
    private Vector3 mouseWorldPos =>
    Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //检测鼠标互动情况
            ClickAction(ObjectAtMousePosition().gameObject);
        }
    }
    private void ClickAction(GameObject clickObject)
    {
        if (clickObject != null)
        {
            switch (clickObject.tag)
            {
                case "Line":
                    var line = clickObject.GetComponent<Line>();
                    line?.Rotate();
                    LevelManager.Instance.StartPowerCommand();
                    break;
            }
        }
    }
    /// <summary>
    /// 检测鼠标点击范围的碰撞体
    /// </summary>
    /// <returns></returns>
    private Collider2D ObjectAtMousePosition()
    {
        return Physics2D.OverlapPoint(mouseWorldPos);
    }
}

单例类

using System;
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    private static T instance;

    public static T Instance
    {
        get { return instance; }
    }

    protected void Awake()
    {
        if (instance != null)
            Destroy(gameObject);
        else
        {
            instance = (T) this;
        }
    }

    public static bool IsInitialized
    {
        get { return instance != null; }
    }

    protected virtual void OnDestroy()
    {
        if (instance == this)
        {
            instance = null;
        }
    }
}

游戏管理类

在场景中创建空物体命名为Level Manager,添加LevelManager.cs单例类

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

public class LevelManager : Singleton<LevelManager>
{
    public Battery battery;
    [Header("场景中存在的线")]
    public GameObject[] lines;
    private void Start()
    {
        lines = GameObject.FindGameObjectsWithTag("Line");
    }
    public void StartPowerCommand()
    {
        //重置所有线的状态
        for (int i = 0; i < lines.Length; i++)
        {
            lines[i].GetComponent<Line>().ResetStatic();
        }

        //这里需要延迟调用一下,因为通过OnTrigger添加对象会有延迟
        Invoke("StartPower", 0.5f);

        //这里需要延迟调运一下,因为电路的递归需要点时间
        Invoke("isGameOver", 0.5f);
    }
    private void StartPower()
    {
        battery.StartPower();
    }
	
    private void isGameOver()
    {
        GameObject gameObject = battery.inLine;
        if (gameObject != null)
        {
            if (gameObject.GetComponent<Line>().isPower) 
                GameOver();
        }
    }
    private void GameOver()
    {
        Debug.Log("GameOver");
    }
}

关卡设计

把所有东西添加成预制体,就可以自由地开始关卡设计了
按住Ctrl可以控制移动距离,还可以自己设置距离
在这里插入图片描述
在这里插入图片描述

总结

多喝热水、少熬夜,心情美美的,一切问题都会应难而解。

最后

以上就是感性大叔为你收集整理的Unity 电路解密小游戏实现思路实现效果功能需求实现思路实现过程总结的全部内容,希望文章能够帮你解决Unity 电路解密小游戏实现思路实现效果功能需求实现思路实现过程总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部